public override void OnStarted() { int channelBitwidth = base.ChannelBitwidth; switch (channelBitwidth) { case 0x20: _streamFlags &= ~BASSFlag.BASS_SAMPLE_8BITS; _streamFlags |= BASSFlag.BASS_SAMPLE_FLOAT; channelBitwidth = 4; break; case 8: _streamFlags &= ~BASSFlag.BASS_SAMPLE_FLOAT; _streamFlags |= BASSFlag.BASS_SAMPLE_8BITS; channelBitwidth = 1; break; default: _streamFlags &= ~BASSFlag.BASS_SAMPLE_FLOAT; _streamFlags &= ~BASSFlag.BASS_SAMPLE_8BITS; channelBitwidth = 2; break; } _streamBuffer = new BASSBuffer(2f, base.ChannelSampleRate, base.ChannelNumChans, channelBitwidth); _stream = Bass.BASS_StreamCreate(base.ChannelSampleRate, base.ChannelNumChans, _streamFlags, null, IntPtr.Zero); Bass.BASS_ChannelSetLink(base.ChannelHandle, _stream); if (Bass.BASS_ChannelIsActive(base.ChannelHandle) == BASSActive.BASS_ACTIVE_PLAYING) { Bass.BASS_ChannelPlay(_stream, false); } }
// Call this before playing any audio void SyncWithStream(AudioStream childStream) { if (audioHandle == childStream.audioHandle) { return; } if (Bass.BASS_ChannelSetLink(this.audioHandle, childStream.audioHandle)) { childSyncedStreams.Add(childStream.audioHandle); } else { var bassError = Bass.BASS_ErrorGetCode(); Debug.LogError("AudioStream SyncWithStream error: " + bassError); } }
// Token: 0x060000BC RID: 188 RVA: 0x0001A8D8 File Offset: 0x00018AD8 public void method_43(string string_2, bool bool_11, Song.Instrument genum18_0 = Song.Instrument.None, Song.Instrument genum18_1 = Song.Instrument.None) { this.method_47(); if (!Directory.Exists(string_2)) { return; } int num = 0; this.bool_7 = true; this.bool_2 = false; GStruct1 gstruct = this.method_60(genum18_0); GStruct1 gstruct2 = this.method_38(genum18_1); for (int i = 1; i < this.stemChannels.Length; i++) { if ((i < gstruct.int_0 || i > gstruct.int_1) && (i < gstruct2.int_0 || i > gstruct2.int_1)) { string text = this.method_15(Path.Combine(string_2, BassAudioManager.stemPaths[i]), -1); if (text != null) { int num2 = Bass.BASS_StreamCreateFile(text, 1L, 0L, BASSFlag.BASS_SAMPLE_MONO | BASSFlag.BASS_SAMPLE_FX); if (num2 == 0) { this.stemChannels[i] = 0; } else { if (i < BassAudioManager.stemPaths.Length - 1) { num += 0; } this.stemChannels[i] = BassFx.BASS_FX_TempoCreate(num2, BASSFlag.BASS_SAMPLE_8BITS | BASSFlag.BASS_SAMPLE_SOFTWARE | BASSFlag.BASS_SAMPLE_VAM); Bass.BASS_ChannelSetAttribute(this.stemChannels[i], (BASSAttribute)(-147), (float)(bool_11 ? (GlobalVariables.instance.songSpeed.CurrentValue - 85) : 0)); long pos = Bass.BASS_ChannelGetLength(this.stemChannels[i]); double num3 = Bass.BASS_ChannelBytes2Seconds(this.stemChannels[i], pos); if (num3 > this.double_0) { this.linkedChannel = this.stemChannels[i]; this.double_0 = num3; } } } } } for (int j = 0; j < this.stemChannels.Length; j++) { if (this.stemChannels[j] != this.linkedChannel) { Bass.BASS_ChannelSetLink(this.linkedChannel, this.stemChannels[j]); } } if (this.stemChannels[1] == 0) { this.stemChannels[1] = this.stemChannels[6]; this.stemChannels[2] = 0; } if (num > 1) { this.bool_7 = true; } this.isSongLoaded = false; this.double_1 = this.double_0; }
// Token: 0x060000A9 RID: 169 RVA: 0x0001A144 File Offset: 0x00018344 public void LoadSong(string songFolder, bool isSpedUp, Song.Instrument excludedInstruments = Song.Instrument.None, Song.Instrument excludedInstruments2 = Song.Instrument.None) { this.method_47(); if (!Directory.Exists(songFolder)) { return; } int num = 0; this.bool_7 = false; this.bool_2 = false; GStruct1 gstruct = this.method_38(excludedInstruments); GStruct1 gstruct2 = this.method_38(excludedInstruments2); for (int i = 0; i < this.stemChannels.Length; i++) { if ((i < gstruct.int_0 || i > gstruct.int_1) && (i < gstruct2.int_0 || i > gstruct2.int_1)) { string text = this.method_15(Path.Combine(songFolder, BassAudioManager.stemPaths[i]), -1); if (text != null) { int num2 = Bass.BASS_StreamCreateFile(text, 0L, 0L, BASSFlag.BASS_STREAM_PRESCAN | BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_ASYNCFILE); if (num2 == 0) { this.stemChannels[i] = 0; } else { if (i < BassAudioManager.stemPaths.Length - 1) { num++; } this.stemChannels[i] = BassFx.BASS_FX_TempoCreate(num2, BASSFlag.BASS_SAMPLE_OVER_VOL); Bass.BASS_ChannelSetAttribute(this.stemChannels[i], BASSAttribute.BASS_ATTRIB_TEMPO, (float)(isSpedUp ? (GlobalVariables.instance.songSpeed.CurrentValue - 100) : 1)); long pos = Bass.BASS_ChannelGetLength(this.stemChannels[i]); double num3 = Bass.BASS_ChannelBytes2Seconds(this.stemChannels[i], pos); if (num3 > this.double_0) { this.linkedChannel = this.stemChannels[i]; this.double_0 = num3; } } } } } for (int j = 0; j < this.stemChannels.Length; j++) { if (this.stemChannels[j] != this.linkedChannel) { Bass.BASS_ChannelSetLink(this.linkedChannel, this.stemChannels[j]); } } if (this.stemChannels[1] == 0) { this.stemChannels[1] = this.stemChannels[2]; this.stemChannels[2] = 0; } if (num > 1) { this.bool_7 = true; } this.isSongLoaded = true; this.double_1 = this.double_0; }
public int PlayFile(ISoundFile file, int fadeInTime, PlayingFinished callback, bool loop) { int channel = 0; BASSFlag speakerFlag = GetSpeakerFlag(file); BASSFlag decodeFlag = BASSFlag.BASS_STREAM_DECODE; if (file.SoundFileType == SoundFileType.Music && file.Effects.SpeakerAssignment.Active) { switch (file.Effects.SpeakerAssignment.Assignment) { case Data.SpeakerAssignment.AllSpeakers: case Data.SpeakerAssignment.BothCenterRears: case Data.SpeakerAssignment.BothFronts: case Data.SpeakerAssignment.BothRears: case Data.SpeakerAssignment.CenterAndSubwoofer: case Data.SpeakerAssignment.Default: break; default: decodeFlag |= BASSFlag.BASS_SAMPLE_MONO; break; } } #if MONO System.Runtime.InteropServices.GCHandle gcHandle = new System.Runtime.InteropServices.GCHandle(); #endif if (file.SoundFileType == SoundFileType.WebRadio) { channel = Bass.BASS_StreamCreateURL(file.Path, 0, decodeFlag | BASSFlag.BASS_STREAM_BLOCK, null, IntPtr.Zero); } else { #if MONO byte[] buffer = null; long length = 0; try { #if ANDROID if (file.Path.IsSmbFile()) { buffer = SambaHelpers.GetFileContent(file.Path); length = buffer.Length; } else { #endif System.IO.FileStream fs = System.IO.File.OpenRead(file.Path); length = fs.Length; buffer = new byte[length]; fs.Read(buffer, 0, (int)length); fs.Close(); #if ANDROID } #endif } catch (System.IO.IOException e) { ErrorHandling.ErrorOccurred(file.Id, e.Message); return(0); } gcHandle = System.Runtime.InteropServices.GCHandle.Alloc(buffer, System.Runtime.InteropServices.GCHandleType.Pinned); channel = Bass.BASS_StreamCreateFile(gcHandle.AddrOfPinnedObject(), 0L, length, decodeFlag); #else // #if MONO channel = Bass.BASS_StreamCreateFile(file.Path, 0, 0, decodeFlag); #endif } if (channel == 0) { #if MONO if (gcHandle.IsAllocated) { gcHandle.Free(); } #endif ErrorHandling.BassErrorOccurred(file.Id, StringResources.FilePlayingError); return(0); } RunningFileInfo info = new RunningFileInfo(); bool isStreaming = BassStreamer.Instance.IsStreaming; bool useMultiSpeakerChannels = false; int speakers = 2; int origChannel = channel; if (!isStreaming && file.Effects != null && file.Effects.SpeakerAssignment.Active && file.Effects.SpeakerAssignment.Assignment == Data.SpeakerAssignment.AllSpeakers && !file.Effects.Balance.Active && !file.Effects.Pitch.Active && !file.Effects.Tempo.Active) { speakers = Bass.BASS_GetInfo().speakers; if (speakers > 2) { useMultiSpeakerChannels = true; } } Un4seen.Bass.BASSFlag flags = BASSFlag.BASS_DEFAULT; if (isStreaming) { flags = BASSFlag.BASS_FX_FREESOURCE | BASSFlag.BASS_STREAM_DECODE; } else if (useMultiSpeakerChannels) { flags = BASSFlag.BASS_FX_FREESOURCE | BASSFlag.BASS_STREAM_DECODE; } else { flags = BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_FX_FREESOURCE | speakerFlag; } channel = Un4seen.Bass.AddOn.Fx.BassFx.BASS_FX_TempoCreate(channel, flags); if (channel == 0) { #if MONO if (gcHandle.IsAllocated) { gcHandle.Free(); } #endif ErrorHandling.BassErrorOccurred(file.Id, StringResources.FilePlayingError); return(0); } bool result = true; if (useMultiSpeakerChannels) { int splitStream = Un4seen.Bass.AddOn.Mix.BassMix.BASS_Split_StreamCreate(channel, BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_SPEAKER_FRONT, null); if (splitStream == 0) { result = false; } else { int splitStream2 = Un4seen.Bass.AddOn.Mix.BassMix.BASS_Split_StreamCreate(channel, BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_SPEAKER_REAR, null); if (splitStream2 == 0) { result = false; } else { Bass.BASS_ChannelSetLink(splitStream, splitStream2); info.LinkedChannels = new List <int>(); info.LinkedChannels.Add(splitStream2); } if (result && speakers > 4) { int splitStream3 = Un4seen.Bass.AddOn.Mix.BassMix.BASS_Split_StreamCreate(channel, BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_SPEAKER_CENLFE, null); if (splitStream3 == 0) { result = false; } else { Bass.BASS_ChannelSetLink(splitStream, splitStream3); info.LinkedChannels.Add(splitStream3); } } if (result && speakers > 6) { int splitStream4 = Un4seen.Bass.AddOn.Mix.BassMix.BASS_Split_StreamCreate(channel, BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_SPEAKER_REAR2, null); if (splitStream4 == 0) { result = false; } else { Bass.BASS_ChannelSetLink(splitStream, splitStream4); info.LinkedChannels.Add(splitStream4); } } if (result) { channel = splitStream; } } } if (result) { lock (m_Mutex) { info.EndAction = new Action(() => { callback(file.Id, channel); }); info.Volume = file.Volume; } if (!loop) { int sync = 0; // If CueOut is active ... if (file.Effects.CueOut.Active) { // Convert the CueOut position (seconds) into a byte offset long cueOutPos = Bass.BASS_ChannelSeconds2Bytes(channel, file.Effects.CueOut.Position); // Set the "end" sync to that position sync = Bass.BASS_ChannelSetSync(channel, BASSSync.BASS_SYNC_POS, cueOutPos, m_CueOutSync, new IntPtr(file.Id)); } else { long totalLength = Bass.BASS_ChannelGetLength(channel); long endingTime = Bass.BASS_ChannelSeconds2Bytes(channel, 0.1); // Default: set the "end" sync to the end of the stream, minus one ms sync = Bass.BASS_ChannelSetSync(channel, BASSSync.BASS_SYNC_POS, totalLength - endingTime, m_StartNextSync, IntPtr.Zero); } if (sync == 0) { #if MONO if (gcHandle.IsAllocated) { gcHandle.Free(); } #endif ErrorHandling.BassErrorOccurred(file.Id, StringResources.FilePlayingError); return(0); } else { lock (m_Mutex) { m_NotLoops[channel] = sync; } } } if (!SetStartVolume(file, fadeInTime, channel, info)) { return(0); } info.CrossFade = false; if (file.Effects != null && file.Effects.FadeOutTime != 0) { long totalLength = Bass.BASS_ChannelGetLength(channel); if (totalLength == -1) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetVolumeError); return(0); } long fadeOutLength = Bass.BASS_ChannelSeconds2Bytes(channel, 0.001 * file.Effects.FadeOutTime); if (fadeOutLength == -1) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetVolumeError); return(0); } if (fadeOutLength > totalLength) { fadeOutLength = totalLength; } // If CueOut is active ... if (file.Effects.CueOut.Active) { // Convert the CueOut position (seconds) into a byte offset long cueOutPos = Bass.BASS_ChannelSeconds2Bytes(channel, file.Effects.CueOut.Position); // Set the "end" sync to that position if (Bass.BASS_ChannelSetSync(channel, BASSSync.BASS_SYNC_POS, cueOutPos - fadeOutLength, m_FadeOutSync, new IntPtr(file.Effects.FadeOutTime)) == 0) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.FilePlayingError); return(0); } } else { if (Bass.BASS_ChannelSetSync(channel, BASSSync.BASS_SYNC_POS, totalLength - fadeOutLength, m_FadeOutSync, new IntPtr(file.Effects.FadeOutTime)) == 0) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.FilePlayingError); return(0); } } if (loop) { // If CueOut is active ... if (file.Effects.CueOut.Active) { // Convert the CueOut position (seconds) into a byte offset long cueOutPos = Bass.BASS_ChannelSeconds2Bytes(channel, file.Effects.CueOut.Position); // Set the "end" sync to that position if (Bass.BASS_ChannelSetSync(channel, BASSSync.BASS_SYNC_POS, cueOutPos, m_LoopSync, new IntPtr(file.Id)) == 0) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.FilePlayingError); return(0); } } else { if (Bass.BASS_ChannelSetSync(channel, BASSSync.BASS_SYNC_POS, totalLength, m_LoopSync, new IntPtr(file.Id)) == 0) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.FilePlayingError); return(0); } } } else { info.CrossFade = file.Effects.CrossFading; } } if (file.Effects != null && file.Effects.Pitch.Active) { float pitchValue = DetermineIntEffectValue(file.Effects.Pitch); if (!Bass.BASS_ChannelSetAttribute(channel, BASSAttribute.BASS_ATTRIB_TEMPO_PITCH, pitchValue)) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetEffectError); return(0); } } if (file.Effects != null && file.Effects.Tempo.Active) { float tempoValue = DetermineIntEffectValue(file.Effects.Tempo); if (!Bass.BASS_ChannelSetAttribute(channel, BASSAttribute.BASS_ATTRIB_TEMPO, tempoValue)) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetEffectError); return(0); } } if (file.Effects != null && file.Effects.Balance.Active && !useMultiSpeakerChannels) { SetBalanceEffect(channel, file.Id, file.Effects.Balance); } if (file.Effects != null && file.Effects.VolumeDB.Active) { float volumeDB = DetermineIntEffectValue(file.Effects.VolumeDB); float linear = (float)Math.Pow(10d, volumeDB / 20); int volFx = Bass.BASS_ChannelSetFX(channel, BASSFXType.BASS_FX_BFX_VOLUME, 1); if (volFx == 0) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetEffectError); return(0); } Un4seen.Bass.AddOn.Fx.BASS_BFX_VOLUME fxVol = new Un4seen.Bass.AddOn.Fx.BASS_BFX_VOLUME(linear, Un4seen.Bass.AddOn.Fx.BASSFXChan.BASS_BFX_CHANALL); if (!Bass.BASS_FXSetParameters(volFx, fxVol)) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetEffectError); return(0); } if (info.LinkedChannels != null) { foreach (int splitStream2 in info.LinkedChannels) { int volFx2 = splitStream2 != 0 ? Bass.BASS_ChannelSetFX(splitStream2, BASSFXType.BASS_FX_BFX_VOLUME, 1) : 0; if (splitStream2 != 0 && volFx2 == 0) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetEffectError); return(0); } if (volFx2 != 0 && !Bass.BASS_FXSetParameters(volFx2, fxVol)) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetEffectError); return(0); } } } } #pragma warning disable CS0618 // Type or member is obsolete if (file.Effects != null && file.Effects.Reverb.Active) { float linearLevel = (float)Math.Pow(10d, file.Effects.Reverb.Level / 20); int reverbFx = Bass.BASS_ChannelSetFX(channel, BASSFXType.BASS_FX_BFX_REVERB, 1); if (reverbFx == 0) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetEffectError); return(0); } Un4seen.Bass.AddOn.Fx.BASS_BFX_REVERB fxReverb = new Un4seen.Bass.AddOn.Fx.BASS_BFX_REVERB(linearLevel, file.Effects.Reverb.Delay); if (!Bass.BASS_FXSetParameters(reverbFx, fxReverb)) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetEffectError); return(0); } if (info.LinkedChannels != null) { foreach (int splitStream2 in info.LinkedChannels) { int reverbFx2 = splitStream2 != 0 ? Bass.BASS_ChannelSetFX(splitStream2, BASSFXType.BASS_FX_BFX_REVERB, 1) : 0; if (splitStream2 != 0 && reverbFx2 == 0) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetEffectError); return(0); } if (reverbFx2 != 0 && !Bass.BASS_FXSetParameters(reverbFx2, fxReverb)) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.SetEffectError); return(0); } } } } #pragma warning restore CS0618 // Type or member is obsolete if (loop) { Bass.BASS_ChannelFlags(channel, BASSFlag.BASS_SAMPLE_LOOP, BASSFlag.BASS_SAMPLE_LOOP); } lock (m_Mutex) { m_Loops[file.Id] = file; if (file.Effects != null && file.Effects.CueOut.Active) { m_CueOutRepeats[channel] = loop; } } if (file.Effects.CueIn.Active) { Bass.BASS_ChannelSetPosition(channel, file.Effects.CueIn.Position); } if (isStreaming) { result = BassStreamer.Instance.AddChannel(channel); } else { result = Bass.BASS_ChannelPlay(channel, false); } if (!result) { ErrorHandling.BassErrorOccurred(file.Id, StringResources.FilePlayingError); Bass.BASS_StreamFree(channel); #if MONO if (gcHandle.IsAllocated) { gcHandle.Free(); } #endif return(0); } lock (m_Mutex) { m_RunningFiles[channel] = info; #if MONO if (gcHandle.IsAllocated) { m_GCHandles[channel] = gcHandle; } #endif } return(channel); } else { ErrorHandling.BassErrorOccurred(file.Id, StringResources.FilePlayingError); return(0); } }
public override void OnStarted() { int num = Bass.BASS_GetDevice(); if (num != this._streamCopyDevice) { Bass.BASS_SetDevice(this._streamCopyDevice); } if (base.ChannelBitwidth == 32) { this._streamCopyFlags &= ~BASSFlag.BASS_SAMPLE_8BITS; this._streamCopyFlags |= BASSFlag.BASS_SAMPLE_FLOAT; } else if (base.ChannelBitwidth == 8) { this._streamCopyFlags &= ~BASSFlag.BASS_SAMPLE_FLOAT; this._streamCopyFlags |= BASSFlag.BASS_SAMPLE_8BITS; } else { this._streamCopyFlags &= ~BASSFlag.BASS_SAMPLE_FLOAT; this._streamCopyFlags &= ~BASSFlag.BASS_SAMPLE_8BITS; } int num2 = Bass.BASS_StreamCreatePush(base.ChannelSampleRate, base.ChannelNumChans, this._streamCopyFlags, IntPtr.Zero); this._streamCopyDelay = 0; if (this.SourceMixerStream == 0) { Bass.BASS_ChannelLock(base.ChannelHandle, true); } else { Bass.BASS_ChannelLock(this.SourceMixerStream, true); } if (this._isOutputBuffered) { if (this.SourceMixerStream != 0) { if (this.TargetMixerStream != 0) { if (base.ChannelInfo.IsDecodingChannel && (BassMix.BASS_Mixer_ChannelFlags(base.ChannelHandle, BASSFlag.BASS_RECORD_ECHOCANCEL, BASSFlag.BASS_DEFAULT) & BASSFlag.BASS_RECORD_ECHOCANCEL) != BASSFlag.BASS_DEFAULT) { int num3 = BassMix.BASS_Mixer_ChannelGetData(base.ChannelHandle, IntPtr.Zero, 0); int num4 = Bass.BASS_ChannelGetData(this.TargetMixerStream, IntPtr.Zero, 0); num4 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, Bass.BASS_ChannelBytes2Seconds(this.TargetMixerStream, (long)num4)); if (num4 > 0) { num3 -= num4; } if (num3 > 0) { int num5 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, (double)this._outputLatency / 1000.0); if (num4 > 0) { num5 = 0; } byte[] array = new byte[num3]; num3 = BassMix.BASS_Mixer_ChannelGetData(base.ChannelHandle, array, num3); if (num3 > num5) { if (num5 > 0) { Array.Copy(array, num5, array, 0, num3 - num5); } Bass.BASS_StreamPutData(num2, array, num3 - num5); } } } else { int num6 = Bass.BASS_ChannelGetData(this.SourceMixerStream, IntPtr.Zero, 0); num6 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, Bass.BASS_ChannelBytes2Seconds(this.SourceMixerStream, (long)num6)); int num7 = Bass.BASS_ChannelGetData(this.TargetMixerStream, IntPtr.Zero, 0); num7 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, Bass.BASS_ChannelBytes2Seconds(this.TargetMixerStream, (long)num7)); num6 -= num7; if (num6 > 0) { int num8 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, (double)this._outputLatency / 1000.0); if (num7 > 0) { num8 = 0; } byte[] array2 = new byte[num6]; if (!base.ChannelInfo.IsDecodingChannel) { num6 = Bass.BASS_ChannelGetData(this.SourceMixerStream, array2, num6); num6 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, Bass.BASS_ChannelBytes2Seconds(this.SourceMixerStream, (long)num6)); } if (num6 > num8) { if (num8 > 0) { Array.Copy(array2, num8, array2, 0, num6 - num8); } Bass.BASS_StreamPutData(num2, array2, num6 - num8); } } } } else if (base.ChannelInfo.IsDecodingChannel && (BassMix.BASS_Mixer_ChannelFlags(base.ChannelHandle, BASSFlag.BASS_RECORD_ECHOCANCEL, BASSFlag.BASS_DEFAULT) & BASSFlag.BASS_RECORD_ECHOCANCEL) != BASSFlag.BASS_DEFAULT) { int num9 = BassMix.BASS_Mixer_ChannelGetData(base.ChannelHandle, IntPtr.Zero, 0); if (num9 > 0) { int num10 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, (double)this._outputLatency / 1000.0); byte[] array3 = new byte[num9]; num9 = BassMix.BASS_Mixer_ChannelGetData(base.ChannelHandle, array3, num9); if (num9 > num10) { if (num10 > 0) { Array.Copy(array3, num10, array3, 0, num9 - num10); } Bass.BASS_StreamPutData(num2, array3, num9 - num10); } } } else { int num11 = Bass.BASS_ChannelGetData(this.SourceMixerStream, IntPtr.Zero, 0); num11 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, Bass.BASS_ChannelBytes2Seconds(this.SourceMixerStream, (long)num11)); if (num11 > 0) { int num12 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, (double)this._outputLatency / 1000.0); byte[] array4 = new byte[num11]; if (!base.ChannelInfo.IsDecodingChannel) { num11 = Bass.BASS_ChannelGetData(this.SourceMixerStream, array4, num11); num11 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, Bass.BASS_ChannelBytes2Seconds(this.SourceMixerStream, (long)num11)); } if (num11 > num12) { if (num12 > 0) { Array.Copy(array4, num12, array4, 0, num11 - num12); } Bass.BASS_StreamPutData(num2, array4, num11 - num12); } } } } else if (!base.ChannelInfo.IsDecodingChannel) { int num13 = (int)Bass.BASS_ChannelSeconds2Bytes(num2, (double)this._outputLatency / 1000.0); int num14 = Bass.BASS_ChannelGetData(base.ChannelHandle, IntPtr.Zero, 0); byte[] array5 = new byte[num14]; num14 = Bass.BASS_ChannelGetData(base.ChannelHandle, array5, num14); if (num14 > num13) { if (num13 > 0) { Array.Copy(array5, num13, array5, 0, num14 - num13); } Bass.BASS_StreamPutData(num2, array5, num14 - num13); } } } this._streamCopy = num2; if (this.TargetMixerStream != 0 && (this._streamCopyFlags & BASSFlag.BASS_STREAM_DECODE) != BASSFlag.BASS_DEFAULT) { BassMix.BASS_Mixer_StreamAddChannel(this.TargetMixerStream, this._streamCopy, ((BassMix.BASS_Mixer_ChannelFlags(base.ChannelHandle, BASSFlag.BASS_RECORD_ECHOCANCEL, BASSFlag.BASS_DEFAULT) & BASSFlag.BASS_RECORD_ECHOCANCEL) != BASSFlag.BASS_DEFAULT) ? BASSFlag.BASS_RECORD_ECHOCANCEL : BASSFlag.BASS_DEFAULT); if (!this._isTargetMixerImmediate && !this._isTargetMixerNonstop) { Bass.BASS_ChannelUpdate(this.TargetMixerStream, 0); } } if ((!base.ChannelInfo.IsDecodingChannel || this.SourceMixerStream != 0) && Bass.BASS_ChannelIsActive(base.ChannelHandle) == BASSActive.BASS_ACTIVE_PLAYING) { Bass.BASS_ChannelPlay(this._streamCopy, false); } if (this.SourceMixerStream == 0) { Bass.BASS_ChannelLock(base.ChannelHandle, false); } else { Bass.BASS_ChannelLock(this.SourceMixerStream, false); } if (!base.ChannelInfo.IsDecodingChannel) { Bass.BASS_ChannelSetLink(base.ChannelHandle, this._streamCopy); } Bass.BASS_SetDevice(num); }