/// <summary> /// Attach a stream to the Mixer /// </summary> /// <param name="stream"></param> /// <returns></returns> public bool AttachStream(MusicStream stream) { Bass.BASS_ChannelLock(_mixer, true); // Set SynyPos at end of stream SetSyncPos(stream, 0.0); bool result = BassMix.BASS_Mixer_StreamAddChannel(_mixer, stream.BassStream, BASSFlag.BASS_MIXER_NORAMPIN | BASSFlag.BASS_MIXER_BUFFER | BASSFlag.BASS_MIXER_MATRIX | BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_STREAM_AUTOFREE); if (!result) { Log.Error("BASS: Error attaching stream to mixer. {0}", Bass.BASS_ErrorGetCode()); } Bass.BASS_ChannelLock(_mixer, false); if (result && _mixingMatrix != null) { Log.Debug("BASS: Setting mixing matrix..."); result = BassMix.BASS_Mixer_ChannelSetMatrix(stream.BassStream, _mixingMatrix); if (!result) { Log.Error("BASS: Error attaching Mixing Matrix. {0}", Bass.BASS_ErrorGetCode()); } } return(result); }
/// <summary> /// Sets the correct mix matrix for the given stream pointer. /// </summary> /// <param name="stream">The stream pointer to set the mix matrix for</param> void SetMatrix(int stream) { if (UpMixToSurround) { var matrix = GetMixMatrix(stream); if (matrix != null) { BassMix.BASS_Mixer_ChannelSetMatrix(stream, matrix); } } }
/// <summary> /// Creates the visualization Bass stream. /// </summary> private void CreateVizStream() { BASSFlag streamFlags = BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT; int handle = Bass.BASS_StreamCreate( _inputStream.SampleRate, _inputStream.Channels, streamFlags, _vizRawStreamWriteProcDelegate, IntPtr.Zero); if (handle == BassConstants.BassInvalidHandle) { throw new BassLibraryException("BASS_StreamCreate"); } _vizRawStream = BassStream.Create(handle); // Todo: apply AGC streamFlags = BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE; handle = BassMix.BASS_Mixer_StreamCreate(_inputStream.SampleRate, 2, streamFlags); if (handle == BassConstants.BassInvalidHandle) { throw new BassLibraryException("BASS_StreamCreate"); } _vizStream = BassStream.Create(handle); streamFlags = BASSFlag.BASS_MIXER_NORAMPIN | BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_MIXER_MATRIX; if (!BassMix.BASS_Mixer_StreamAddChannel(_vizStream.Handle, _vizRawStream.Handle, streamFlags)) { throw new BassLibraryException("BASS_Mixer_StreamAddChannel"); } // TODO Albert 2010-02-27: What is this? if (_inputStream.Channels == 1) { float[,] mixMatrix = new float[2, 1]; mixMatrix[0, 0] = 1; mixMatrix[1, 0] = 1; if (!BassMix.BASS_Mixer_ChannelSetMatrix(_vizRawStream.Handle, mixMatrix)) { throw new BassLibraryException("BASS_Mixer_ChannelSetMatrix"); } } }
private void UpdateMatrix(int index) { double dhandle; this.FPinHandles[index].GetValue(0, out dhandle); ChannelInfo info = this.manager.GetChannel(Convert.ToInt32(dhandle)); if (info != null) { int mixerhandle = 0; if (info.BassHandle.HasValue) { mixerhandle = BassMix.BASS_Mixer_ChannelGetMixer(info.BassHandle.Value); } if (mixerhandle != 0) { BASS_CHANNELINFO MIXER = Bass.BASS_ChannelGetInfo(mixerhandle); BASS_CHANNELINFO CHANNEL = Bass.BASS_ChannelGetInfo(info.BassHandle.Value); float[,] matrix = new float[MIXER.chans, CHANNEL.chans]; BassMix.BASS_Mixer_ChannelGetMatrix(info.BassHandle.Value, matrix); int idx = 0; for (int i = 0; i < MIXER.chans; i++) { for (int j = 0; j < CHANNEL.chans; j++) { double level; this.FPinLevels[index].GetValue(idx, out level); matrix[i, j] = (float)level; idx++; if (idx == this.FPinLevels[index].SliceCount) { idx = 0; } } } BassMix.BASS_Mixer_ChannelSetMatrix(info.BassHandle.Value, matrix); } } }
private void buttonPlaySource_Click(object sender, System.EventArgs e) { Bass.BASS_StreamFree(_streamA); Bass.BASS_StreamFree(_streamB); Bass.BASS_StreamFree(_mixerStream); // mixer setup // now we need some channels to plug them in...create two decoding sources _streamA = Bass.BASS_StreamCreateFile(_fileName, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT); _streamB = Bass.BASS_StreamCreateFile(_fileNameOutput, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT); BASS_CHANNELINFO i = new BASS_CHANNELINFO(); Bass.BASS_ChannelGetInfo(_streamA, i); // this will be the final mixer output stream being played _mixerStream = BassMix.BASS_Mixer_StreamCreate(i.freq, 4, BASSFlag.BASS_DEFAULT); // finally we plug them into the mixer (and upmix it to 4 channels - we assume the source to be stereo) bool okA = BassMix.BASS_Mixer_StreamAddChannel(_mixerStream, _streamA, BASSFlag.BASS_MIXER_MATRIX | BASSFlag.BASS_STREAM_AUTOFREE); bool okB = BassMix.BASS_Mixer_StreamAddChannel(_mixerStream, _streamB, BASSFlag.BASS_STREAM_AUTOFREE); // a matrix for A! float[,] matrixA = new float[4, 2] { // stereo to quad matrix { 1, 0 }, // left front out = left in { 0, 1 }, // right front out = right in { 1, 0 }, // left rear out = left in { 0, 1 } // right rear out = right in }; // apply the matrix to stream A only BassMix.BASS_Mixer_ChannelSetMatrix(_streamA, matrixA); // just so show how to get it back... float[,] matrixGet = new float[4, 2]; BassMix.BASS_Mixer_ChannelGetMatrix(_streamA, matrixGet); // mute streamB at the beginning this.trackBarCrossFader.Value = -100; Bass.BASS_ChannelSetAttribute(_streamB, BASSAttribute.BASS_ATTRIB_VOL, 0f); // and play it... if (Bass.BASS_ChannelPlay(_mixerStream, false)) { this.label1.Text = "Playing! Use the crossfader..."; } }
/// <summary> /// Create a mixer to be used as Output stream. /// We currently need this in case of Up- or Downmixing /// </summary> private void CreateMixer(int channels) { _mixerHandle = BassMix.BASS_Mixer_StreamCreate(_inputStream.SampleRate, channels, MIXER_FLAGS); if (_mixerHandle == BassConstants.BassInvalidHandle) { throw new BassLibraryException("BASS_Mixer_StreamCreate"); } _mixerStream = BassStream.Create(_mixerHandle); // Now Attach the Input Stream to the mixer try { Bass.BASS_ChannelLock(_mixerHandle, true); bool result = BassMix.BASS_Mixer_StreamAddChannel(_mixerHandle, _inputStream.Handle, BASSFlag.BASS_MIXER_NORAMPIN | BASSFlag.BASS_MIXER_BUFFER | BASSFlag.BASS_MIXER_MATRIX | BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_STREAM_AUTOFREE ); if (!result) { throw new BassLibraryException("BASS_UpDownMix_StreamAddChannel"); } } finally { Bass.BASS_ChannelLock(_mixerHandle, false); } if (_mixingMatrix != null) { bool result = BassMix.BASS_Mixer_ChannelSetMatrix(_inputStream.Handle, _mixingMatrix); if (!result) { throw new BassLibraryException("BASS_UpDownMix_SetMixingMatrix"); } } }
public bool DownmixMogg(string CON_file, string output, MoggSplitFormat format, string quality, bool doWii = false, double start = 0.0, double length = 0.0, double fadeIn = 0.0, double fadeOut = 0.0, double volume = 0.0, string stems = "allstems") { if (!ExtractDecryptMogg(CON_file, true)) { return(false); } try { if (!InitBass()) { return(false); } var BassStream = Bass.BASS_StreamCreateFile(Tools.GetOggStreamIntPtr(), 0, Tools.PlayingSongOggData.Length, BASSFlag.BASS_STREAM_DECODE); var channel_info = Bass.BASS_ChannelGetInfo(BassStream); var BassMixer = BassMix.BASS_Mixer_StreamCreate(doWii ? 22050 : channel_info.freq, 2, BASSFlag.BASS_MIXER_END | BASSFlag.BASS_STREAM_DECODE); if (doWii) { BassMix.BASS_Mixer_StreamAddChannelEx(BassMixer, BassStream, BASSFlag.BASS_MIXER_MATRIX, 0, Bass.BASS_ChannelSeconds2Bytes(BassMixer, length)); var track_vol = (float)Utils.DBToLevel(Convert.ToDouble(volume), 1.0); Bass.BASS_ChannelSetPosition(BassStream, Bass.BASS_ChannelSeconds2Bytes(BassStream, start)); BASS_MIXER_NODE[] nodes = { new BASS_MIXER_NODE(0, 0), new BASS_MIXER_NODE(Bass.BASS_ChannelSeconds2Bytes(BassMixer, fadeIn), track_vol), new BASS_MIXER_NODE(Bass.BASS_ChannelSeconds2Bytes(BassMixer, length - fadeOut),track_vol), new BASS_MIXER_NODE(Bass.BASS_ChannelSeconds2Bytes(BassMixer, length), 0) }; BassMix.BASS_Mixer_ChannelSetEnvelope(BassStream, BASSMIXEnvelope.BASS_MIXER_ENV_VOL, nodes, nodes.Count()); } else { BassMix.BASS_Mixer_StreamAddChannel(BassMixer, BassStream, BASSFlag.BASS_MIXER_MATRIX); } var matrix = GetChannelMatrix(Parser.Songs[0], channel_info.chans, stems); BassMix.BASS_Mixer_ChannelSetMatrix(BassStream, matrix); var output_file = output; if (string.IsNullOrWhiteSpace(output)) { output_file = Path.GetDirectoryName(CON_file) + "\\" + Parser.Songs[0].InternalName + (format == MoggSplitFormat.WAV ? ".wav" : ".ogg"); } if (format == MoggSplitFormat.OGG) { var cmd = "bin\\oggenc2.exe -q" + quality + " - -o\"" + output_file + "\""; BassEnc.BASS_Encode_Start(BassMixer, cmd, BASSEncode.BASS_ENCODE_FP_24BIT | BASSEncode.BASS_ENCODE_AUTOFREE, null, IntPtr.Zero); } else { BassEnc.BASS_Encode_Start(BassMixer, output_file, BASSEncode.BASS_ENCODE_PCM | BASSEncode.BASS_ENCODE_AUTOFREE, null, IntPtr.Zero); } while (true) { var buffer = new byte[20000]; var c = Bass.BASS_ChannelGetData(BassMixer, buffer, buffer.Length); if (c < 0) { break; } } UnloadLibraries(); Tools.ReleaseStreamHandle(); return(File.Exists(output_file)); } catch (Exception ex) { ErrorLog.Add("Error downmixing mogg file:"); ErrorLog.Add(ex.Message); UnloadLibraries(); Tools.ReleaseStreamHandle(); return(false); } }