Author Topic: How to use Bass.BASS_StreamCreateURL Method on its own thread?  (Read 3546 times)

kabindi

  • Posts: 25
I have been playing with Bass.BASS_StreamCreateURL Method on windows form using C# 4.0. I can play the music but the UI freezes and it sucks. I figured I should make sure that my function runs on its own new thread but I don't know how to do it. Can someone please help me out? Here is my function so far:
Code: [Select]
public bool PlayUrl(string url)
        {
            // init BASS using the default output device
            if (Bass.BASS_Init(-1, DefaultSampleRate, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero))
            {
                //---- Create the new stream

                // BASSStream.BASS_STREAM_PRESCAN |
                int streamHandle = Bass.BASS_StreamCreateURL(url, 0, BASSFlag.BASS_STREAM_STATUS, null, IntPtr.Zero);

                lock (StreamLock)
                {
                    if (Stream != 0)
                        Bass.BASS_StreamFree(Stream);

                    Stream = streamHandle;

                    // Play the stream
                    if (Stream != 0)
                    {
                        Bass.BASS_ChannelPlay(Stream, false);
                    }
                }

                return true;
            }
            return false;
        }

radio42

  • Posts: 4574
Doesn't really sound like a BASS relkated question, but more like a general 'How to implement Multi-Threading in C#'.

Either try some searing in the web or use one of the following link:

http://msdn.microsoft.com/en-us/library/ms173178(v=vs.100).aspx
http://www.c-sharpcorner.com/UploadFile/mgold/MultithreadingIntro10062005000439AM/MultithreadingIntro.aspx
http://www.codeplanet.eu/tutorials/csharp/64-multithreading-in-csharp.html

kabindi

  • Posts: 25

The problem is that I have already tried to implement that using the conventional threat methods and it doesn't work.

Code: [Select]
  private Thread _onlineFileWorker;
 public void PlayUrlAsync(string url)
        {
            try
            {
                if (_onlineFileWorker != null)
                {
                    _onlineFileWorker.Abort();
                    _onlineFileWorker = null;
                }

                Stop();

                if (Stream != 0)
                {
                    Position = 0;
                    Un4seen.Bass.Bass.BASS_StreamFree(Stream);
                    Stream = 0;
                }
                _onlineFileWorker = new Thread(new ThreadStart(() =>
                {
                    int handle = Un4seen.Bass.Bass.BASS_StreamCreateURL(url, 0, Un4seen.Bass.BASSFlag.BASS_SAMPLE_FLOAT |
                                                                        Un4seen.Bass.BASSFlag.BASS_STREAM_PRESCAN, null, IntPtr.Zero);

                    Application.Current.Dispatcher.BeginInvoke(new Action(() =>
                    {
                        if (handle != 0)
                        {
                            Stream = handle;
                            Length = Un4seen.Bass.Bass.BASS_ChannelBytes2Seconds(Stream, Un4seen.Bass.Bass.BASS_ChannelGetLength(Stream, 0));
                            Un4seen.Bass.BASS_CHANNELINFO info = new Un4seen.Bass.BASS_CHANNELINFO();
                            Un4seen.Bass.Bass.BASS_ChannelGetInfo(Stream, info);
                            //  _sampleFrequency = info.freq;

                            int syncHandle = Un4seen.Bass.Bass.BASS_ChannelSetSync(Stream,
                                 Un4seen.Bass.BASSSync.BASS_SYNC_END,
                                 0,
                                 _endTrackSyncProc,
                                 IntPtr.Zero);

                            if (syncHandle == 0)
                                throw new ArgumentException("Error establishing End Sync on file stream.", "path");

                            switch (PlayBackState)
                            {
                                case PlayState.Paused:
                                    {
                                        Play();
                                        break;
                                    }
                                case PlayState.Playing:
                                    {
                                        Pause();
                                        break;
                                    }
                                default:
                                    {
                                        Play();
                                        break;
                                    }
                            }
                        }
                        else
                        {
                            Debug.WriteLine(Un4seen.Bass.Bass.BASS_ErrorGetCode());
                        }
                    }));
                }));
                _onlineFileWorker.IsBackground = true;
                _onlineFileWorker.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());

                throw;
            }
        }

radio42

  • Posts: 4574
ANd at which line of code does your UI 'freeze'?

kabindi

  • Posts: 25
I get a System.NullReferenceException. I guess the problem has to do with the way I'm creating my thread; Here is my exception
Code: [Select]

System.NullReferenceException was unhandled
  Message=Object reference not set to an instance of an object.
  Source=UrlStreamTest
  StackTrace:
       at UrlStreamTest.AudioPlayer.<>c__DisplayClass8.<OpenUrlAsync>b__5() in \\psf\home\documents\visual studio 2010\Projects\UrlStreamTest\UrlStreamTest\AudioPlayer.cs:line 507
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

radio42

  • Posts: 4574
And what is at line 507 ?
Can post that code ... or is that already somewhere contained in your above posted code?
If yes, where?

kabindi

  • Posts: 25
Revision: I'm trying to make my thread as simple as possible. I have modified the complicated code into something simpler but still I get a base error:BASS_ERROR_HANDLE

Code: [Select]
public void OpenUrl(string url)
        {
            Bass.BASS_StreamFree(stream);

            Thread t =
                new Thread(
                    (object o) =>
                    stream =
                    Bass.BASS_StreamCreateURL(url, 0, BASSFlag.BASS_SAMPLE_SOFTWARE, null,
                                              this.Handle));
            t.Start(url);

            if (stream != 0)
            {
                // play the stream channel
                Bass.BASS_ChannelPlay(stream, false);
            }
            else
            {
                // error creating the stream

                MessageBox.Show("Stream error: {0}" + Bass.BASS_ErrorGetCode());
            }
        }

        private void Start(string url)
        {
          

            // init BASS using the default output device
            if (Bass.BASS_Init(-1, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero))
            {
                // create a stream channel from a file

                Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_NET_PLAYLIST, 2);

                stream = Bass.BASS_StreamCreateURL(url, 0, BASSFlag.BASS_DEFAULT, null,
                                                   IntPtr.Zero);

                if (stream != 0)
                {
                    // play the stream channel
                    Bass.BASS_ChannelPlay(stream, false);
                }
                else
                {
                    // error creating the stream
                    MessageBox.Show("Stream error: {0}" + Bass.BASS_ErrorGetCode());
                }
            }
        }
Strangely enough I get this Error: BASS_ERROR_HANDLE

Ian @ un4seen

  • Administrator
  • Posts: 20400
Isn't the problem that the OpenUrl function is trying to play the new stream before it has actually been created, ie. before the "t" thread has finished calling BASS_StreamCreateURL? You could try moving the BASS_ChannelPlay call into the thread.

kabindi

  • Posts: 25
Just tried that. It doesn't work

radio42

  • Posts: 4574
What Ian said is totally correct!
Please send you 'revisioned' code!
Also note, that you might get a BASS_ErrorGetCode from the initial "BASS_StreamFree" call.

Hoewever, you didn't answer my last question!

kabindi

  • Posts: 25
I didn't answer you question because I revised the code and couldn't remember what was there. After going back, at line 507 it is just the start of the thread at
Code: [Select]
Application.Current.Dispatcher.BeginInvoke(
                                                           new Action(() =>

As for the revised code, here it is:
Code: [Select]

  public void OpenUrl(string url)
        {
            Bass.BASS_StreamFree(stream);

            Thread t =
                new Thread(
                    (object o) =>
                    stream =
                    Bass.BASS_StreamCreateURL(url, 0, BASSFlag.BASS_DEFAULT, null,
                                              this.Handle)
                                             
                                             
);

            if (stream != 0)
            {
                // play the stream channel
                Bass.BASS_ChannelPlay(stream, false);
            }
            else
            {
                // error creating the stream

                MessageBox.Show("Stream error: {0}" + Bass.BASS_ErrorGetCode());
            }
            t.Start(url);

        }

        private void Start(string url)
        {
            stream = Bass.BASS_StreamCreateURL(url, 0, BASSFlag.BASS_DEFAULT, null,
                                               IntPtr.Zero);

            if (stream != 0)
            {
                // play the stream channel
                Bass.BASS_ChannelPlay(stream, false);
            }
            else
            {
                // error creating the stream
                MessageBox.Show("Stream error: {0}" + Bass.BASS_ErrorGetCode());
            }
        }