/// <summary>
        /// Attach a stream to the Mixer
        /// </summary>
        /// <returns></returns>
        public bool AttachStream()
        {
            try
            {
                Bass.BASS_ChannelLock(_mixerHandle, true);

                RegisterStreamFreedEvent(_inputStream);

                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_Mixer_StreamAddChannel");
                }

                return(true);
            }
            finally
            {
                Bass.BASS_ChannelLock(_mixerHandle, false);
            }
        }
Exemple #2
0
        private void buttonAddFile_Click(object sender, EventArgs e)
        {
            if (DialogResult.OK == openFileDialog.ShowDialog(this))
            {
                if (File.Exists(openFileDialog.FileName))
                {
                    lock (listBoxPlaylist)
                    {
                        Track track = new Track(openFileDialog.FileName);
                        listBoxPlaylist.Items.Add(track);

                        // in the demo we already add each new track to the mixer
                        // this is in real life not the best place to do so (especially with larger playlists)
                        // but for the demo it is okay ;-)

                        // add the new track to the mixer (in PAUSED mode!)
                        BassMix.BASS_Mixer_StreamAddChannel(_mixer, track.Channel, BASSFlag.BASS_MIXER_PAUSE | BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_STREAM_AUTOFREE);

                        // an BASS_SYNC_END is used to trigger the next track in the playlist (if no POS sync was set)
                        track.TrackSync = new SYNCPROC(OnTrackSync);
                        BassMix.BASS_Mixer_ChannelSetSync(track.Channel, BASSSync.BASS_SYNC_END, 0L, track.TrackSync, new IntPtr(0));
                    }

                    if (_currentTrack == null)
                    {
                        PlayNextTrack();
                    }
                }
            }
        }
Exemple #3
0
        /// <summary>
        ///   Recode the file
        /// </summary>
        /// <param name = "fileName">Initial file</param>
        /// <param name = "outFileName">Target file</param>
        /// <param name = "targetSampleRate">Target sample rate</param>
        public void RecodeTheFile(string fileName, string outFileName, int targetSampleRate)
        {
            int      stream = Un4seen.Bass.Bass.BASS_StreamCreateFile(fileName, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_MONO | BASSFlag.BASS_SAMPLE_FLOAT);
            TAG_INFO tags   = new TAG_INFO();

            BassTags.BASS_TAG_GetFromFile(stream, tags);
            int mixerStream = BassMix.BASS_Mixer_StreamCreate(targetSampleRate, 1, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_MONO | BASSFlag.BASS_SAMPLE_FLOAT);

            if (BassMix.BASS_Mixer_StreamAddChannel(mixerStream, stream, BASSFlag.BASS_MIXER_FILTER))
            {
                WaveWriter waveWriter = new WaveWriter(outFileName, mixerStream, true);
                const int  length     = 5512 * 10 * 4;
                float[]    buffer     = new float[length];
                while (true)
                {
                    int bytesRead = Un4seen.Bass.Bass.BASS_ChannelGetData(mixerStream, buffer, length);
                    if (bytesRead == 0)
                    {
                        break;
                    }
                    waveWriter.Write(buffer, bytesRead);
                }
                waveWriter.Close();
            }
            else
            {
                throw new Exception(Un4seen.Bass.Bass.BASS_ErrorGetCode().ToString());
            }
        }
Exemple #4
0
        /// <summary>
        /// Adds to the mixer channel, and sets the sync points.
        /// </summary>
        /// <param name="sample">The sample to sync.</param>
        private void AddSampleToMixer(Sample sample)
        {
            if (sample == null)
            {
                return;
            }

            Debug.Print("Add sample to mixer " + sample.Description);

            // load audio data if not loaded
            if (sample.Channel == int.MinValue)
            {
                LoadSampleAudioData(sample);
            }

            //if (sample != this.PreviousSample && sample != this.CurrentSample)
            //{
            // add the new sample to the mixer (in paused mode)
            //BassMix.BASS_Mixer_StreamAddChannel(_mixerChannel, sample.Channel, BASSFlag.BASS_MIXER_PAUSE | BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_STREAM_AUTOFREE);
            BassMix.BASS_Mixer_StreamAddChannel(_sampleMixerChannel, sample.Channel, BASSFlag.BASS_MIXER_PAUSE | BASSFlag.BASS_MIXER_DOWNMIX);

            //// set sample sync event
            //sample.SampleSync = new SYNCPROC(OnSampleSync);

            //// set replay gain
            //BassHelper.SetSampleReplayGain(sample.Channel, sample.Gain);
            //}
        }
Exemple #5
0
        public void start(double delay)
        {
            latency = (float)delay / 10;
            var str   = (inlist.Items[inlist.SelectedIndex] as string);
            var array = str.Split(' ');

            sourceIndex = Convert.ToInt32(array[0]);
            str         = (outlist.Items[outlist.SelectedIndex] as string);
            array       = str.Split(' ');
            outIndex    = Convert.ToInt32(array[0]);
            Console.WriteLine(sourceIndex + " " + outIndex);
            Console.WriteLine(delay);

            stop();
            Bass.BASS_Init(0, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero); // "No Sound" device init

            // Garbage collector can't track the reference BassWasapi holds,
            // so we're adding a reference here to prevent garbage collection
            inProc  = sourceWasapiProc;
            outProc = outWasapiProc;
            BassWasapi.BASS_WASAPI_Init(sourceIndex, 44100, 0, 0, 1, 0, inProc, IntPtr.Zero);
            BassWasapi.BASS_WASAPI_Init(outIndex, 44100, 0, 0, 4 * latency, 1 * latency, outProc, IntPtr.Zero);

            BassWasapi.BASS_WASAPI_SetDevice(outIndex);
            pushstr = Bass.BASS_StreamCreatePush(44100, 2, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT, IntPtr.Zero);
            outstr  = BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT);
            BassMix.BASS_Mixer_StreamAddChannel(outstr, pushstr, 0);

            BassWasapi.BASS_WASAPI_SetDevice(sourceIndex);
            BassWasapi.BASS_WASAPI_Start();
            BassWasapi.BASS_WASAPI_SetDevice(outIndex);
            BassWasapi.BASS_WASAPI_Start();
        }
        public void LoadSample(Sample sample)
        {
            if (sample.FileName == null)
            {
                return;
            }
            if (sample.FileName.EndsWith(".wma"))
            {
                sample.Channel = BassWma.BASS_WMA_StreamCreateFile(sample.FileName, 0L, 0L,
                                                                   BASSFlag.BASS_STREAM_DECODE |
                                                                   BASSFlag.BASS_SAMPLE_FLOAT);
            }
            else
            {
                sample.Channel = Bass.BASS_StreamCreateFile(sample.FileName, 0L, 0L,
                                                            BASSFlag.BASS_STREAM_DECODE |
                                                            BASSFlag.BASS_SAMPLE_FLOAT);
            }

            BassMix.BASS_Mixer_StreamAddChannel(SoundEffectMixerChannel, sample.Channel,
                                                BASSFlag.BASS_MIXER_PAUSE);
            Bass.BASS_ChannelSetSync(sample.Channel, BASSSync.BASS_SYNC_END, 0, endSync, IntPtr.Zero);

            //sample.Weight = 1;

            if (CurrentSample == null)
            {
                CurrentSample = sample;
            }
            SetLoop();
        }
        /// <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);
        }
Exemple #8
0
        public void Resample_8To8()  //broken only on Linux?
        {
            //-- 1. Create a raw sine sample which shall be 44100 Hz and 16 Bit
            int sampleLength = 500;

            byte[] buffer = new byte[sampleLength];
            for (int i = 0; i < sampleLength; i++)
            {
                buffer [i] = (byte)(128 + 120.0f * Math.Sin(((float)i / (float)sampleLength) * (Math.PI * 2.0f)));
            }

            using (BinaryWriter writerRaw = new BinaryWriter(File.Open("test2_in_sine_44100_8.raw", FileMode.Create))) {
                for (uint i = 0; i < sampleLength; i++)
                {
                    writerRaw.Write(buffer [i]);
                }
            }

            GCHandle _hGCFile;

            // now create a pinned handle, so that the Garbage Collector will not move this object
            _hGCFile = GCHandle.Alloc(buffer, GCHandleType.Pinned);

            int handle = Bass.BASS_StreamCreate(44100, 1, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_8BITS, BASSStreamProc.STREAMPROC_PUSH);

            int ret = Bass.BASS_StreamPutData(handle, _hGCFile.AddrOfPinnedObject(), buffer.Length * sizeof(byte) | (int)BASSStreamProc.BASS_STREAMPROC_END);

            Assert.AreEqual(buffer.Length * sizeof(byte), ret);


            //-- 2. Mix it
            int mixer = BassMix.BASS_Mixer_StreamCreate(11025, 1, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_8BITS);

            // add channel to mixer
            bool isMixerGood = BassMix.BASS_Mixer_StreamAddChannel(mixer, handle, BASSFlag.BASS_MIXER_NORAMPIN);

            Assert.AreEqual(true, isMixerGood);

            //-- 3. grab Stream and compare
            byte[] buffer2 = new byte[1000];

            // total data written to the new byte[] buffer
            int totalDataWritten = Bass.BASS_ChannelGetData(mixer, buffer2, (int)1000);

            Console.WriteLine("totalDataWritten " + totalDataWritten);

            using (BinaryWriter writerRaw = new BinaryWriter(File.Open("test2_out_sine_11025_8.raw", FileMode.Create))) {
                for (uint i = 0; i < totalDataWritten; i++)
                {
                    writerRaw.Write(buffer2 [i]);
                }
            }

            string hashGen = MD5Utils.GenerateMd5Hash(buffer2);

            Bass.BASS_StreamFree(handle);
            Bass.BASS_StreamFree(mixer);

            Assert.AreEqual("50bce9c536e98667534747f0a5f06ebd", hashGen);
        }
Exemple #9
0
        public void AttachChannel(ChannelInfo info)
        {
            if (info is InputChannelInfo)
            {
                InputChannelInfo iinfo = (InputChannelInfo)info;
                if (this.BassHandle.HasValue)
                {
                    BassMix.BASS_Mixer_StreamAddChannel(this.BassHandle.Value, iinfo.Handler.OutputChannel, BASSFlag.BASS_MIXER_MATRIX | BASSFlag.BASS_MIXER_BUFFER);
                }
            }
            else
            {
                if (!info.BassHandle.HasValue)
                {
                    //Initialize to no sound as it's decoding anyway
                    info.Initialize(0);
                }
                this.streams.Add(info);

                if (this.BassHandle.HasValue)
                {
                    BassMix.BASS_Mixer_StreamAddChannel(this.BassHandle.Value, info.BassHandle.Value, BASSFlag.BASS_MIXER_MATRIX | BASSFlag.BASS_MIXER_BUFFER);
                }
                //Simple trick to refresh play status now it's attached
            }
            info.Play = info.Play;
        }
Exemple #10
0
        public void StreamAddChannel(int channel, SYNCPROC trackSync)
        {
            //BassMix.BASS_Mixer_StreamAddChannel(Player.Mixer, channel, BASSFlag.BASS_MIXER_PAUSE | BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_MIXER_DOWNMIX);
            BassMix.BASS_Mixer_StreamAddChannel(Player.Mixer, channel, BASSFlag.BASS_MIXER_PAUSE | BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_STREAM_AUTOFREE);

            // an BASS_SYNC_END is used to trigger the next track in the playlist (if no POS sync was set)
            BassMix.BASS_Mixer_ChannelSetSync(channel, BASSSync.BASS_SYNC_END, 0L, trackSync, new IntPtr(1));
        }
Exemple #11
0
 void Scenes_ListChanged(object sender, ListChangedEventArgs e)
 {
     if (e.ListChangedType == ListChangedType.ItemAdded)
     {
         Scenes[e.NewIndex].StoppingOthers += new EventHandler(Module_StoppingOthers);
         BassMix.BASS_Mixer_StreamAddChannel(ModuleMixerChannel, Scenes[e.NewIndex].SceneMixerChannel,
                                             BASSFlag.BASS_DEFAULT);
     }
 }
Exemple #12
0
 void SoundEffects_ListChanged(object sender, ListChangedEventArgs e)
 {
     Stop(false);
     if (e.ListChangedType == ListChangedType.ItemAdded)
     {
         BassMix.BASS_Mixer_StreamAddChannel(SceneMixerChannel, SoundEffects[e.NewIndex].SoundEffectMixerChannel,
                                             BASSFlag.BASS_DEFAULT);
     }
 }
        public bool AddMixerChannel(int source)
        {
            int mixer = this.StreamMixer;

            this.StreamMixer = mixer;

            this.StreamPlugged = source;

            return(BassMix.BASS_Mixer_StreamAddChannel(mixer, source, BASSFlag.BASS_MIXER_NORAMPIN));
        }
        /// <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");
                }
            }
        }
Exemple #15
0
 public bool loadDeckB(string songName)
 {
     if (running())
     {
         if (!songName.Equals(string.Empty))
         {
             _songB    = songName;
             _deckB    = Bass.BASS_StreamCreateFile(songName, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT);
             _bRunning = false;                       // definitely not playing
             bool b = BassMix.BASS_Mixer_StreamAddChannel(_mixer, _deckB, BASSFlag.BASS_DEFAULT);
             BassMix.BASS_Mixer_ChannelPause(_deckB); // pause as soon as it loads
             return(b);
         }
     }
     return(false);
 }
Exemple #16
0
        /// <summary>
        /// Creates the channel.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <returns></returns>
        public ITrack CreateChannel(string file)
        {
            var channelHandle = Bassh.BASS_StreamCreateFile(file, 0, 0, BASSFlag.BASS_SAMPLE_FLOAT | BASSFlag.BASS_STREAM_DECODE);

            Bassh.BASS_ChannelSetAttribute(channelHandle, BASSAttribute.BASS_ATTRIB_SRC, 2);
            Debug.WriteLine(Bassh.BASS_ChannelGetInfo(channelHandle));
            if (0 == channelHandle)
            {
                throw new InvalidOperationException("Unable to create stream");
            }
            if (!BassMix.BASS_Mixer_StreamAddChannel(mixerHandle, channelHandle, BASSFlag.BASS_MIXER_PAUSE | BASSFlag.BASS_MIXER_BUFFER | BASSFlag.BASS_MIXER_NORAMPIN))
            {
                Trace.WriteLine(Bassh.BASS_ErrorGetCode());
                throw new InvalidOperationException("Unable to add channel to mixer.");
            }
            return(new BassTrack(channelHandle, mixerHandle, file));
        }
Exemple #17
0
        public static int PlugChannelToMixer(int handle, int freq, int chans, int res)
        {
            BASSFlag bassFlag = BASSFlag.BASS_STREAM_DECODE;

            if (res == 8)
            {
                bassFlag |= BASSFlag.BASS_SAMPLE_8BITS;
            }

            // this will be the final mixer output stream being played
            int mixer = BassMix.BASS_Mixer_StreamCreate(freq, chans, bassFlag);

            // add channel to mixer
            bool isMixerGood = BassMix.BASS_Mixer_StreamAddChannel(mixer, handle, BASSFlag.BASS_MIXER_NORAMPIN);

            return(mixer);
        }
Exemple #18
0
        /// <summary>
        /// Called when a stream has been created. This actually starts the playback of the stream.
        /// </summary>
        /// <param name="track">The track that is to be played.</param>
        /// <param name="stream">The BASS.NET stream pointer to play.</param>
        protected virtual void StreamCreated(IAudioItem track, int stream)
        {
            // Init mixer
            if (_mixer == -1)
            {
                _mixer = BassMix.BASS_Mixer_StreamCreate(44100, 6, BASSFlag.BASS_MIXER_END);

                // Set playback done callback on mixer
                _channelEndCallback = new SYNCPROC(ChannelEnd);
                Bass.BASS_ChannelSetSync(_mixer, BASSSync.BASS_SYNC_END | BASSSync.BASS_SYNC_MIXTIME, 0, _channelEndCallback, IntPtr.Zero);
            }

            // Load streamin mixer
            bool ok = BassMix.BASS_Mixer_StreamAddChannel(_mixer, stream, BASSFlag.BASS_STREAM_AUTOFREE | BASSFlag.BASS_MIXER_MATRIX);

            if (!ok)
            {
                Log(Bass.BASS_ErrorGetCode().ToString(), Logger.LogLevel.Error);
            }

            // Set matrix
            SetMatrix(stream);

            // Remove current channel from mixer
            if (_currentStream != -1)
            {
                BassMix.BASS_Mixer_ChannelRemove(_currentStream);
                Bass.BASS_StreamFree(_currentStream);
            }

            //
            if (track is IWebcast)
            {
                SYNCPROC _mySync = new SYNCPROC(MetaSync);
                Bass.BASS_ChannelSetSync(_currentStream, BASSSync.BASS_SYNC_META, 0, _mySync, IntPtr.Zero);
            }

            // Play it!
            Bass.BASS_ChannelSetPosition(_mixer, 0);
            Bass.BASS_Start();
            Bass.BASS_ChannelPlay(_mixer, false);

            // Set current stuff
            _currentStream = stream;
        }
Exemple #19
0
        public bool AddOutputSource(int channel, BASSFlag flags)
        {
            BASS_CHANNELINFO bass_CHANNELINFO = Bass.Bass.BASS_ChannelGetInfo(channel);

            if (bass_CHANNELINFO == null)
            {
                return(false);
            }
            if (!bass_CHANNELINFO.IsDecodingChannel && bass_CHANNELINFO.ctype != BASSChannelType.BASS_CTYPE_RECORD)
            {
                return(false);
            }
            if (flags < BASSFlag.BASS_SPEAKER_FRONT)
            {
                flags |= BASSFlag.BASS_WV_STEREO;
            }
            return(BassMix.BASS_Mixer_StreamAddChannel(this._internalMixer, channel, flags));
        }
Exemple #20
0
        public override void Load(string file)
        {
            // Dispose on every new load
            Dispose(false);

            ready = false;

            // Create a stream channel from a file (use BASS_STREAM_PRESCAN for mp3?)
            bassStream = Bass.BASS_StreamCreateFile(file, 0L, 0L, BASSFlag.BASS_STREAM_DECODE);
            if (bassStream != 0)
            {
                var info = Bass.BASS_ChannelGetInfo(bassStream);

                this.sourceBitDepth   = info.Is8bit ? 8 : (info.Is32bit ? 32 : 16);
                this.sourceSampleRate = info.freq;
                this.sourceChannels   = info.chans;

                this.sampleRate = info.freq;
                this.channels   = info.chans;

                duration = (int)Bass.BASS_ChannelBytes2Seconds(bassStream, Bass.BASS_ChannelGetLength(bassStream));

                if (this.resample)
                {
                    this.sampleRate = 11025;
                    this.channels   = 1;

                    // Create resample stream.
                    bassMixer = BassMix.BASS_Mixer_StreamCreate(this.sampleRate, this.channels,
                                                                BASSFlag.BASS_MIXER_END | BASSFlag.BASS_STREAM_DECODE);

                    if (bassMixer == 0)
                    {
                        return;
                    }

                    BassMix.BASS_Mixer_StreamAddChannel(bassMixer, bassStream, 0);
                }

                ready = (!info.Is8bit && !info.Is32bit);
            }
        }
Exemple #21
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...";
            }
        }
Exemple #22
0
        public static void Play(string file, bool loadOnly)
        {
            Stop();
            baseStreamHandle = Bass.BASS_StreamCreateFile(file, 0, 0, BASSFlag.BASS_STREAM_DECODE);
            BASS_CHANNELINFO info = Bass.BASS_ChannelGetInfo(baseStreamHandle);

            mixStreamHandle = BassMix.BASS_Mixer_StreamCreate(info.freq, info.chans, BASSFlag.BASS_STREAM_DECODE);
            BassMix.BASS_Mixer_StreamAddChannel(mixStreamHandle, baseStreamHandle, BASSFlag.BASS_MIXER_MATRIX);
            streamHandle = BassFx.BASS_FX_TempoCreate(mixStreamHandle, BASSFlag.BASS_FX_FREESOURCE);
            Mono         = mono;
            Speed        = speed;
            if (!loadOnly)
            {
                Bass.BASS_ChannelPlay(streamHandle, false);
            }
            BASSError er = Bass.BASS_ErrorGetCode();

            syncProc = new SYNCPROC(AudioEnded);
            Bass.BASS_ChannelSetSync(streamHandle, BASSSync.BASS_SYNC_END, 0, syncProc, IntPtr.Zero);
            Playing    = !loadOnly;
            FileLoaded = true;
        }
Exemple #23
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");
                }
            }
        }
Exemple #24
0
        public void Play_With_Buildup()
        {
            Stop();
            if (InitBass(HZ))
            {
                Channel = BassMix.BASS_Mixer_StreamCreate(HZ, 2, BASSFlag.BASS_MIXER_END);

                point_B = GCHandle.Alloc(build_mem, GCHandleType.Pinned);
                point_L = GCHandle.Alloc(loop_mem, GCHandleType.Pinned);

                Stream_B  = Bass.BASS_StreamCreateFile(point_B.AddrOfPinnedObject(), 0, build_mem.LongLength, BASSFlag.BASS_STREAM_DECODE);
                build_len = Bass.BASS_ChannelGetLength(Stream_B, BASSMode.BASS_POS_BYTES);

                Stream_L = Bass.BASS_StreamCreateFile(point_L.AddrOfPinnedObject(), 0, loop_mem.LongLength, BASSFlag.BASS_STREAM_DECODE);
                loop_len = Bass.BASS_ChannelGetLength(Stream_L);

                BassMix.BASS_Mixer_StreamAddChannel(Channel, Stream_B, BASSFlag.BASS_DEFAULT);
                BassMix.BASS_Mixer_StreamAddChannelEx(Channel, Stream_L, BASSFlag.BASS_MIXER_NORAMPIN, build_len, 0);

                _loopSync = BassMix.BASS_Mixer_ChannelSetSync(Stream_L, BASSSync.BASS_SYNC_POS | BASSSync.BASS_SYNC_MIXTIME, loop_len, _loopSyncCallback, new IntPtr(1));
            }
        }
Exemple #25
0
        public override void Initialize(int deviceid)
        {
            Bass.BASS_SetDevice(deviceid);

            BASSFlag flag = BASSFlag.BASS_DEFAULT | BASSFlag.BASS_SAMPLE_FLOAT;

            if (this.IsDecoding)
            {
                flag = flag | BASSFlag.BASS_STREAM_DECODE;
            }

            int handle = BassMix.BASS_Mixer_StreamCreate(44100, this.NumChans, flag);

            this.BassHandle = handle;

            //Add the channel list in bass now
            foreach (ChannelInfo info in this.Streams)
            {
                if (!info.BassHandle.HasValue)
                {
                    info.Initialize(deviceid);
                }
                else
                {
                    if (info.BassHandle.Value == 0)
                    {
                        info.Initialize(deviceid);
                    }
                }
                BassMix.BASS_Mixer_StreamAddChannel(this.BassHandle.Value, info.BassHandle.Value, BASSFlag.BASS_MIXER_MATRIX | BASSFlag.BASS_MIXER_BUFFER);
                info.Play = info.Play;
            }

            this.Play = this.Play;

            //Bass.BASS_ChannelPlay(this.BassHandle.Value, false);
            this.OnInitialize();
        }
        /// <summary>
        ///     Adds an audio stream to a mixer
        /// </summary>
        /// <param name="audioStream">The audio stream.</param>
        /// <param name="mixerChannel">The mixer channel.</param>
        public static void AddToMixer(AudioStream audioStream, MixerChannel mixerChannel)
        {
            if (audioStream == null || !audioStream.IsAudioLoaded())
            {
                throw new Exception("Audio file null or not audio not loaded");
            }

            if (mixerChannel.ChannelId == int.MinValue)
            {
                throw new Exception("Mixer channel not initialized");
            }

            // DebugHelper.WriteLine($"AddToMixer {audioStream.Description} {mixerChannel} {audioStream.Channel}...");

            BassMix.BASS_Mixer_StreamAddChannel(mixerChannel.ChannelId, audioStream.ChannelId,
                                                BASSFlag.BASS_MIXER_PAUSE | BASSFlag.BASS_MIXER_DOWNMIX | BASSFlag.BASS_MIXER_NORAMPIN |
                                                BASSFlag.BASS_MUSIC_AUTOFREE);
            Thread.Sleep(1);

            audioStream.MixerChannelId = mixerChannel.ChannelId;

            // DebugHelper.WriteLine("done");
        }
Exemple #27
0
        private void ProcessStreamData(byte[] buffer, int offset, int length)
        {
            if (length < 1)
            {
                return;
            }

            // Write compressed audio data to Circulairbuffer
            byte[] data = new byte[length];
            Buffer.BlockCopy(buffer, offset, data, 0, length);
            lock (lockObject)
            {
                cbbChunkAudio.Write(buffer, offset, length);
            }


            // If basshandle wasn't opened then open it now (when there is enough data. Min 4010 bytes)
            if (inputHandle == 0 && cbbChunkAudio.UsedBytes >= 8000)
            {
                // bass needs for mp3 atleast 4000 bytes before is can play
                inputHandle = Bass.BASS_StreamCreateFileUser(BASSStreamSystem.STREAMFILE_BUFFERPUSH, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT, bassFileProcs, GCHandle.ToIntPtr((GCHandle)gcHandle));
                Bass.BASS_ChannelSetSync(inputHandle, BASSSync.BASS_SYNC_STALL, 0, bassStalledSync, GCHandle.ToIntPtr((GCHandle)gcHandle));
                Bass.BASS_ChannelSetSync(inputHandle, BASSSync.BASS_SYNC_END, 0, bassEndSync, GCHandle.ToIntPtr((GCHandle)gcHandle));

                mixerHandle = BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_FLOAT);
                BassMix.BASS_Mixer_StreamAddChannel(mixerHandle, inputHandle, BASSFlag.BASS_MIXER_FILTER | BASSFlag.BASS_MIXER_DOWNMIX);
                Bass.BASS_ChannelPlay(inputHandle, false);
                Bass.BASS_ChannelPlay(mixerHandle, false);
                return;
            }

            // push new audiodata when available (and basstream is opened)
            if (inputHandle != 0)
            {
                // voed bass met audio data zodat deze het naar pcm data kan decompressen
                long bassBufLen = Bass.BASS_StreamGetFilePosition(inputHandle, BASSStreamFilePosition.BASS_FILEPOS_END);
                long bassBufPos = Bass.BASS_StreamGetFilePosition(inputHandle, BASSStreamFilePosition.BASS_FILEPOS_BUFFER);
                int  todo       = Convert.ToInt32(bassBufLen - bassBufPos);
                if (todo > 0)
                {
                    int count      = todo;
                    int writeBytes = 0;
                    while (!cbbChunkAudio.IsEmpty && todo > 0 && writeBytes > -1)
                    {
                        if (count > 16384)
                        {
                            count = 16384;
                        }
                        byte[] tmpBuffer = new byte[count];
                        lock (lockObject)
                        {
                            count = cbbChunkAudio.Read(tmpBuffer, count);
                        }
                        if (count > 0)
                        {
                            writeBytes = Bass.BASS_StreamPutFileData(inputHandle, tmpBuffer, count);
                            todo      -= writeBytes;
                        }
                    } //while audio buffer not empty
                }
                ProcessDecompressedData();
            }
        }
Exemple #28
0
        /// <summary>
        ///   Read mono from file
        /// </summary>
        /// <param name = "filename">Name of the file</param>
        /// <param name = "samplerate">Sample rate</param>
        /// <param name = "milliseconds">milliseconds to read</param>
        /// <param name = "startmillisecond">Start millisecond</param>
        /// <returns>Array of samples</returns>
        public float[] ReadMonoFromFile(string filename, int samplerate, int milliseconds, int startmillisecond)
        {
            int totalmilliseconds = milliseconds <= 0 ? Int32.MaxValue : milliseconds + startmillisecond;

            float[] data = null;
            //create streams for re-sampling
            int stream = Un4seen.Bass.Bass.BASS_StreamCreateFile(filename, 0, 0, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_MONO | BASSFlag.BASS_SAMPLE_FLOAT);             //Decode the stream

            if (stream == 0)
            {
                throw new Exception(Un4seen.Bass.Bass.BASS_ErrorGetCode().ToString());
            }
            int mixerStream = BassMix.BASS_Mixer_StreamCreate(samplerate, 1, BASSFlag.BASS_STREAM_DECODE | BASSFlag.BASS_SAMPLE_MONO | BASSFlag.BASS_SAMPLE_FLOAT);

            if (mixerStream == 0)
            {
                throw new Exception(Un4seen.Bass.Bass.BASS_ErrorGetCode().ToString());
            }

            if (BassMix.BASS_Mixer_StreamAddChannel(mixerStream, stream, BASSFlag.BASS_MIXER_FILTER))
            {
                const int      bufferSize = 5512 * 10 * 4;        /*read ten seconds at each iteration*/
                float[]        buffer     = new float[bufferSize];
                List <float[]> chunks     = new List <float[]>();
                int            size       = 0;
                while ((float)(size) / samplerate * 1000 < totalmilliseconds)
                {
                    //get re-sampled/mono data
                    int bytesRead = Un4seen.Bass.Bass.BASS_ChannelGetData(mixerStream, buffer, bufferSize);
                    if (bytesRead == 0)
                    {
                        break;
                    }
                    float[] chunk = new float[bytesRead / 4];                   //each float contains 4 bytes
                    Array.Copy(buffer, chunk, bytesRead / 4);
                    chunks.Add(chunk);
                    size += bytesRead / 4;                   //size of the data
                }

                if ((float)(size) / samplerate * 1000 < (milliseconds + startmillisecond))
                {
                    return(null);                    /*not enough samples to return the requested data*/
                }
                int start = (int)((float)startmillisecond * samplerate / 1000);
                int end   = (milliseconds <= 0) ? size : (int)((float)(startmillisecond + milliseconds) * samplerate / 1000);
                data = new float[size];
                int index = 0;
                /*Concatenate*/
                foreach (float[] chunk in chunks)
                {
                    Array.Copy(chunk, 0, data, index, chunk.Length);
                    index += chunk.Length;
                }
                /*Select specific part of the song*/
                if (start != 0 || end != size)
                {
                    float[] temp = new float[end - start];
                    Array.Copy(data, start, temp, 0, end - start);
                    data = temp;
                }
            }
            else
            {
                throw new Exception(Un4seen.Bass.Bass.BASS_ErrorGetCode().ToString());
            }
            return(data);
        }
Exemple #29
0
 public bool CombineMixerStreams(int mixerStream, int stream, BASSFlag flags)
 {
     return(BassMix.BASS_Mixer_StreamAddChannel(mixerStream, stream, flags));
 }
        // メソッド

        public CSoundDeviceASIO(long n希望バッファサイズms, int _nASIODevice)
        {
            // 初期化。

            Trace.TraceInformation("BASS (ASIO) の初期化を開始します。");
            this.e出力デバイス            = ESoundDeviceType.Unknown;
            this.n実出力遅延ms           = 0;
            this.n経過時間ms            = 0;
            this.n経過時間を更新したシステム時刻ms = CTimer.n未使用;
            this.tmシステムタイマ          = new CTimer();
            this.nASIODevice        = _nASIODevice;

            #region [ BASS registration ]
            // BASS.NET ユーザ登録(BASSスプラッシュが非表示になる)。
            BassNet.Registration("*****@*****.**", "2X9181017152222");
            #endregion

            #region [ BASS Version Check ]
            // BASS のバージョンチェック。
            int nBASSVersion = Utils.HighWord(Bass.BASS_GetVersion());
            if (nBASSVersion != Bass.BASSVERSION)
            {
                throw new DllNotFoundException(string.Format("bass.dll のバージョンが異なります({0})。このプログラムはバージョン{1}で動作します。", nBASSVersion, Bass.BASSVERSION));
            }

            int nBASSMixVersion = Utils.HighWord(BassMix.BASS_Mixer_GetVersion());
            if (nBASSMixVersion != BassMix.BASSMIXVERSION)
            {
                throw new DllNotFoundException(string.Format("bassmix.dll のバージョンが異なります({0})。このプログラムはバージョン{1}で動作します。", nBASSMixVersion, BassMix.BASSMIXVERSION));
            }

            int nBASSASIO = Utils.HighWord(BassAsio.BASS_ASIO_GetVersion());
            if (nBASSASIO != BassAsio.BASSASIOVERSION)
            {
                throw new DllNotFoundException(string.Format("bassasio.dll のバージョンが異なります({0})。このプログラムはバージョン{1}で動作します。", nBASSASIO, BassAsio.BASSASIOVERSION));
            }
            #endregion

            // BASS の設定。

            this.bIsBASSFree = true;

            if (!Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_UPDATEPERIOD, 0))           // 0:BASSストリームの自動更新を行わない。
            {
                Trace.TraceWarning($"BASS_SetConfig({nameof(BASSConfig.BASS_CONFIG_UPDATEPERIOD)}) に失敗しました。[{Bass.BASS_ErrorGetCode()}]");
            }
            if (!Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_UPDATETHREADS, 0))           // 0:BASSストリームの自動更新を行わない。
            {
                Trace.TraceWarning($"BASS_SetConfig({nameof(BASSConfig.BASS_CONFIG_UPDATETHREADS)}) に失敗しました。[{Bass.BASS_ErrorGetCode()}]");
            }

            // BASS の初期化。

            int nデバイス = 0;                      // 0:"no device" … BASS からはデバイスへアクセスさせない。アクセスは BASSASIO アドオンから行う。
            int n周波数  = 44100;                  // 仮決め。最終的な周波数はデバイス(≠ドライバ)が決める。
            if (!Bass.BASS_Init(nデバイス, n周波数, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero))
            {
                throw new Exception(string.Format("BASS の初期化に失敗しました。(BASS_Init)[{0}]", Bass.BASS_ErrorGetCode().ToString()));
            }

            Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_CURVE_VOL, true);

//Debug.WriteLine( "BASS_Init()完了。" );
            #region [ デバッグ用: ASIOデバイスのenumerateと、ログ出力 ]
//			CEnumerateAllAsioDevices.GetAllASIODevices();
//Debug.WriteLine( "BassAsio.BASS_ASIO_GetDeviceInfo():" );
//            int a, count = 0;
//            BASS_ASIO_DEVICEINFO asioDevInfo;
//            for ( a = 0; ( asioDevInfo = BassAsio.BASS_ASIO_GetDeviceInfo( a ) ) != null; a++ )
//            {
//                Trace.TraceInformation( "ASIO Device {0}: {1}, driver={2}", a, asioDevInfo.name, asioDevInfo.driver );
//                count++; // count it
//            }
            #endregion

            // BASS ASIO の初期化。
            BASS_ASIO_INFO asioInfo = null;
            if (BassAsio.BASS_ASIO_Init(nASIODevice, BASSASIOInit.BASS_ASIO_THREAD))                    // 専用スレッドにて起動
            {
                #region [ ASIO の初期化に成功。]
                //-----------------
                this.e出力デバイス           = ESoundDeviceType.ASIO;
                asioInfo               = BassAsio.BASS_ASIO_GetInfo();
                this.n出力チャンネル数         = asioInfo.outputs;
                this.db周波数             = BassAsio.BASS_ASIO_GetRate();
                this.fmtASIOデバイスフォーマット = BassAsio.BASS_ASIO_ChannelGetFormat(false, 0);

                Trace.TraceInformation("BASS を初期化しました。(ASIO, デバイス:\"{0}\", 入力{1}, 出力{2}, {3}Hz, バッファ{4}~{6}sample ({5:0.###}~{7:0.###}ms), デバイスフォーマット:{8})",
                                       asioInfo.name,
                                       asioInfo.inputs,
                                       asioInfo.outputs,
                                       this.db周波数.ToString("0.###"),
                                       asioInfo.bufmin, asioInfo.bufmin * 1000 / this.db周波数,
                                       asioInfo.bufmax, asioInfo.bufmax * 1000 / this.db周波数,
                                       this.fmtASIOデバイスフォーマット.ToString()
                                       );
                this.bIsBASSFree = false;
                #region [ debug: channel format ]
                //BASS_ASIO_CHANNELINFO chinfo = new BASS_ASIO_CHANNELINFO();
                //int chan = 0;
                //while ( true )
                //{
                //    if ( !BassAsio.BASS_ASIO_ChannelGetInfo( false, chan, chinfo ) )
                //        break;
                //    Debug.WriteLine( "Ch=" + chan + ": " + chinfo.name.ToString() + ", " + chinfo.group.ToString() + ", " + chinfo.format.ToString() );
                //    chan++;
                //}
                #endregion
                //-----------------
                #endregion
            }
            else
            {
                #region [ ASIO の初期化に失敗。]
                //-----------------
                BASSError errcode = Bass.BASS_ErrorGetCode();
                string    errmes  = errcode.ToString();
                if (errcode == BASSError.BASS_OK)
                {
                    errmes = "BASS_OK; The device may be dissconnected";
                }
                Bass.BASS_Free();
                this.bIsBASSFree = true;
                throw new Exception(string.Format("BASS (ASIO) の初期化に失敗しました。(BASS_ASIO_Init)[{0}]", errmes));
                //-----------------
                #endregion
            }


            // ASIO 出力チャンネルの初期化。

            this.tAsioProc = new ASIOPROC(this.tAsio処理);                                  // アンマネージに渡す delegate は、フィールドとして保持しておかないとGCでアドレスが変わってしまう。
            if (!BassAsio.BASS_ASIO_ChannelEnable(false, 0, this.tAsioProc, IntPtr.Zero)) // 出力チャンネル0 の有効化。
            {
                #region [ ASIO 出力チャンネルの初期化に失敗。]
                //-----------------
                BassAsio.BASS_ASIO_Free();
                Bass.BASS_Free();
                this.bIsBASSFree = true;
                throw new Exception(string.Format("Failed BASS_ASIO_ChannelEnable() [{0}]", BassAsio.BASS_ASIO_ErrorGetCode().ToString()));
                //-----------------
                #endregion
            }
            for (int i = 1; i < this.n出力チャンネル数; i++)                            // 出力チャネルを全てチャネル0とグループ化する。
            {                                                                   // チャネル1だけを0とグループ化すると、3ch以上の出力をサポートしたカードでの動作がおかしくなる
                if (!BassAsio.BASS_ASIO_ChannelJoin(false, i, 0))
                {
                    #region [ 初期化に失敗。]
                    //-----------------
                    BassAsio.BASS_ASIO_Free();
                    Bass.BASS_Free();
                    this.bIsBASSFree = true;
                    throw new Exception(string.Format("Failed BASS_ASIO_ChannelJoin({1}) [{0}]", BassAsio.BASS_ASIO_ErrorGetCode().ToString(), i));
                    //-----------------
                    #endregion
                }
            }
            if (!BassAsio.BASS_ASIO_ChannelSetFormat(false, 0, this.fmtASIOチャンネルフォーマット))                        // 出力チャンネル0のフォーマット
            {
                #region [ ASIO 出力チャンネルの初期化に失敗。]
                //-----------------
                BassAsio.BASS_ASIO_Free();
                Bass.BASS_Free();
                this.bIsBASSFree = true;
                throw new Exception(string.Format("Failed BASS_ASIO_ChannelSetFormat() [{0}]", BassAsio.BASS_ASIO_ErrorGetCode().ToString()));
                //-----------------
                #endregion
            }

            // ASIO 出力と同じフォーマットを持つ BASS ミキサーを作成。

            var flag = BASSFlag.BASS_MIXER_NONSTOP | BASSFlag.BASS_STREAM_DECODE;               // デコードのみ=発声しない。ASIO に出力されるだけ。
            if (this.fmtASIOデバイスフォーマット == BASSASIOFormat.BASS_ASIO_FORMAT_FLOAT)
            {
                flag |= BASSFlag.BASS_SAMPLE_FLOAT;
            }
            this.hMixer = BassMix.BASS_Mixer_StreamCreate((int)this.db周波数, this.n出力チャンネル数, flag);

            if (this.hMixer == 0)
            {
                BASSError err = Bass.BASS_ErrorGetCode();
                BassAsio.BASS_ASIO_Free();
                Bass.BASS_Free();
                this.bIsBASSFree = true;
                throw new Exception(string.Format("BASSミキサ(mixing)の作成に失敗しました。[{0}]", err));
            }

            // BASS ミキサーの1秒あたりのバイト数を算出。

            var mixerInfo    = Bass.BASS_ChannelGetInfo(this.hMixer);
            int nサンプルサイズbyte = 0;
            switch (this.fmtASIOチャンネルフォーマット)
            {
            case BASSASIOFormat.BASS_ASIO_FORMAT_16BIT: nサンプルサイズbyte = 2; break;

            case BASSASIOFormat.BASS_ASIO_FORMAT_24BIT: nサンプルサイズbyte = 3; break;

            case BASSASIOFormat.BASS_ASIO_FORMAT_32BIT: nサンプルサイズbyte = 4; break;

            case BASSASIOFormat.BASS_ASIO_FORMAT_FLOAT: nサンプルサイズbyte = 4; break;
            }
            //long nミキサーの1サンプルあたりのバイト数 = /*mixerInfo.chans*/ 2 * nサンプルサイズbyte;
            long nミキサーの1サンプルあたりのバイト数 = mixerInfo.chans * nサンプルサイズbyte;
            this.nミキサーの1秒あたりのバイト数 = nミキサーの1サンプルあたりのバイト数 * mixerInfo.freq;


            // 単純に、hMixerの音量をMasterVolumeとして制御しても、
            // ChannelGetData()の内容には反映されない。
            // そのため、もう一段mixerを噛ませて、一段先のmixerからChannelGetData()することで、
            // hMixerの音量制御を反映させる。
            this.hMixer_DeviceOut = BassMix.BASS_Mixer_StreamCreate(
                (int)this.db周波数, this.n出力チャンネル数, flag);
            if (this.hMixer_DeviceOut == 0)
            {
                BASSError errcode = Bass.BASS_ErrorGetCode();
                BassAsio.BASS_ASIO_Free();
                Bass.BASS_Free();
                this.bIsBASSFree = true;
                throw new Exception(string.Format("BASSミキサ(最終段)の作成に失敗しました。[{0}]", errcode));
            }
            {
                bool b1 = BassMix.BASS_Mixer_StreamAddChannel(this.hMixer_DeviceOut, this.hMixer, BASSFlag.BASS_DEFAULT);
                if (!b1)
                {
                    BASSError errcode = Bass.BASS_ErrorGetCode();
                    BassAsio.BASS_ASIO_Free();
                    Bass.BASS_Free();
                    this.bIsBASSFree = true;
                    throw new Exception(string.Format("BASSミキサ(最終段とmixing)の接続に失敗しました。[{0}]", errcode));
                }
                ;
            }


            // 出力を開始。

            this.nバッファサイズsample = (int)(n希望バッファサイズms * this.db周波数 / 1000.0);
            //this.nバッファサイズsample = (int)  nバッファサイズbyte;
            if (!BassAsio.BASS_ASIO_Start(this.nバッファサイズsample))                         // 範囲外の値を指定した場合は自動的にデフォルト値に設定される。
            {
                BASSError err = BassAsio.BASS_ASIO_ErrorGetCode();
                BassAsio.BASS_ASIO_Free();
                Bass.BASS_Free();
                this.bIsBASSFree = true;
                throw new Exception("ASIO デバイス出力開始に失敗しました。" + err.ToString());
            }
            else
            {
                int n遅延sample   = BassAsio.BASS_ASIO_GetLatency(false);                 // この関数は BASS_ASIO_Start() 後にしか呼び出せない。
                int n希望遅延sample = (int)(n希望バッファサイズms * this.db周波数 / 1000.0);
                this.n実バッファサイズms = this.n実出力遅延ms = (long)(n遅延sample * 1000.0f / this.db周波数);
                Trace.TraceInformation("ASIO デバイス出力開始:バッファ{0}sample(希望{1}) [{2}ms(希望{3}ms)]", n遅延sample, n希望遅延sample, this.n実出力遅延ms, n希望バッファサイズms);
            }
        }