예제 #1
0
        /// <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);
        }
예제 #2
0
 /// <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);
         }
     }
 }
예제 #3
0
        /// <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");
                }
            }
        }
예제 #4
0
        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);
                }
            }
        }
예제 #5
0
        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...";
            }
        }
예제 #6
0
        /// <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");
                }
            }
        }
예제 #7
0
 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);
     }
 }