/// <summary>
        /// Saves the partial as wave.
        /// </summary>
        /// <param name="inFilename">The in filename.</param>
        /// <param name="outFilename">The out filename.</param>
        /// <param name="start">The start position in seconds.</param>
        /// <param name="length">The length in seconds.</param>
        /// <param name="offset">The offset position in seconds.</param>
        /// <param name="gain">The gain.</param>
        /// <param name="bpm">The BPM.</param>
        /// <param name="targetBpm">The target BPM.</param>
        public static void SavePartialAsWave(string inFilename, 
            string outFilename, 
            double start,
            double length,
            double offset = 0, 
            float gain = 0, 
            decimal bpm = 0, 
            decimal targetBpm = 0)
        {
            DebugHelper.WriteLine("Saving portion of track as wave with offset - " + inFilename);

            var audioStream = new Sample()
            {
                Filename = inFilename,
                Description = inFilename,
                Gain = gain,
                Bpm = bpm
            };

            AudioStreamHelper.LoadAudio(audioStream);

            //var channel = Bass.BASS_StreamCreateFile(inFilename, 0L, 0L,
            //    BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_STREAM_PRESCAN);
            //if (channel == 0) throw new Exception("Cannot load track " + inFilename);

            //if (gain > 0)
            //    AudioStreamHelper.SetReplayGain(channel, gain);

            if (targetBpm != 0 && bpm != 0)
                AudioStreamHelper.SetTempoToMatchBpm(audioStream.Channel, bpm, targetBpm);
            
            const BASSEncode flags = BASSEncode.BASS_ENCODE_PCM;
            BassEnc.BASS_Encode_Start(audioStream.Channel, outFilename, flags, null, IntPtr.Zero);

            var startByte = Bass.BASS_ChannelSeconds2Bytes(audioStream.Channel, start); 
            var endByte = Bass.BASS_ChannelSeconds2Bytes(audioStream.Channel, start + length);
            if (offset == 0 || offset == start)
            {
                TransferBytes(audioStream.Channel, startByte, endByte);
            }
            else
            {
                startByte = Bass.BASS_ChannelSeconds2Bytes(audioStream.Channel, offset);
                TransferBytes(audioStream.Channel, startByte, endByte);

                startByte = Bass.BASS_ChannelSeconds2Bytes(audioStream.Channel, start);
                endByte = Bass.BASS_ChannelSeconds2Bytes(audioStream.Channel, offset);
                TransferBytes(audioStream.Channel, startByte, endByte);
            }

            BassEnc.BASS_Encode_Stop(audioStream.Channel);

            Bass.BASS_StreamFree(audioStream.Channel);
        }
        /// <summary>
        ///     Saves the specified sample as a mono wave in the Scratch folder and launches Scratch
        /// </summary>
        /// <param name="sample">The sample.</param>
        public static void Launch(Sample sample)
        {
            if (_applicationFolder == "") return;
            if (sample == null) return;

            SilenceHelper.GenerateSilenceAudioFile(GetSilenceFilename());
            SaveSample(sample);

            var gain = GetGain(sample.Filename);

            var scratchFilePath = Path.Combine(_applicationFolder, ScratchFile);
            AudioExportHelper.SaveAsMonoWave(sample.Filename, scratchFilePath, gain);
            

            var scratchExePath = Path.Combine(_applicationFolder, ScratchExe);
            Process.Start(scratchExePath);
        }
        /// <summary>
        ///     Saves a shortened version the specified sample as a mono wave in the Scratch folder and launches Scratch
        /// </summary>
        /// <param name="sample">The sample.</param>
        public static void LaunchShort(Sample sample)
        {
            if (_applicationFolder == "") return;

            SilenceHelper.GenerateSilenceAudioFile(GetSilenceFilename());
            SaveSample(sample);

            var bpm = BpmHelper.GetBpmFromLoopLength(sample.LengthSeconds);
            var loopLength = BpmHelper.GetDefaultLoopLength(bpm);
            var shortLength = loopLength/8;
            if (shortLength > sample.LengthSeconds) shortLength = sample.LengthSeconds;

            var gain = GetGain(sample.Filename);
            var scratchFilePath = Path.Combine(_applicationFolder, ScratchFile);
            AudioExportHelper.SaveAsMonoWave(sample.Filename, scratchFilePath, shortLength, gain);

            var scratchExePath = Path.Combine(_applicationFolder, ScratchExe);
            Process.Start(scratchExePath);
        }
        public AudioStream Load(string streamKey, string filename)
        {
            if (!File.Exists(filename))
                throw new Exception("Cannot find file " + filename);
            if (GetStreamSection(streamKey) != null)
                throw new Exception("AudioStream already exists with streamKey " + streamKey);

            var audioStream = new Sample
            {
                Filename = filename
            };

            var tags = TagHelper.LoadTags(filename);
            if (tags != null)
            {
                if (tags.Gain.HasValue)
                    audioStream.Gain = tags.Gain.Value;
                if (tags.Bpm.HasValue)
                    audioStream.Bpm = tags.Bpm.Value;

                audioStream.Description = TrackHelper.GuessTrackDescription(filename, tags.Artist, tags.Title);
            }

            AudioStreamHelper.LoadAudio(audioStream);

            audioStream.SyncProc = OnSync;
            AudioStreamHelper.AddToMixer(audioStream, Output.ChannelId);
            AudioStreamHelper.SetPosition(audioStream, 0);

            lock (_streamSections)
            {
                _streamSections.Add(new AudioStreamSection
                {
                    Key = streamKey,
                    AudioStream = audioStream,
                    AudioSections = new List<AudioSection>()
                });
            }

            return audioStream;
        }
        private void StartRecordingSampleTrigger(Sample sample)
        {
            if (CurrentTrack == null) return;
            if (sample == null) return;

            LastSampleTriggerTrack = CurrentTrack;
            LastSampleTriggerNextTrackDescription = NextTrack == null ? "" : NextTrack.Description;
            LastSampleTriggerPrevTrackDescription = PreviousTrack == null ? "" : PreviousTrack.Description;

            var position = AudioStreamHelper.GetPosition(LastSampleTriggerTrack);

            LastSampleTrigger = new SampleTrigger
            {
                Start = LastSampleTriggerTrack.SamplesToSeconds(position),
                DelayNotes = SamplerDelayNotes,
                SampleId = sample.SampleId
            };
        }
 /// <summary>
 ///     Sets the sample.
 /// </summary>
 /// <param name="sample">The sample.</param>
 public void SetSample(Sample sample)
 {
     Sample = sample;
     BindData();
 }