Author Topic: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))  (Read 8440 times)

cablehead

  • Posts: 315
With my NetRadio type app if a user tries to connect to a different station while the tags are updating via the current  tagsync...

elCrasho...everytime.

Any way to catch this? (Bass.NET C#)

radio42

  • Posts: 4573
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #1 on: 6 Sep '08 - 09:39 »
Can you please show some of your code where your app is crashing.

cablehead

  • Posts: 315
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #2 on: 6 Sep '08 - 23:29 »
Its simple...Im debugging...I see the sync is updating the tags...

I click to connect to another station/stream...crash.
When I try this new connect I call stream_free on the playing stream.

Crashes only if the sync is updating.

radio42

  • Posts: 4573
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #3 on: 8 Sep '08 - 09:30 »
As stated in the docs,
"...Some functions can cause problems if called from within a stream, sync (or DSP) function. Do not call these functions from within a callback: BASS_Stop, BASS_Free, BASS_MusicLoad, BASS_StreamCreate or any other stream creation functions. Also, do not call BASS_StreamFree or BASS_ChannelStop with the same handle as received by the callback..."

Guess this is what you are doing in the SYNCPROC?

Ian @ un4seen

  • Administrator
  • Posts: 20393
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #4 on: 8 Sep '08 - 12:43 »
Yep. A stream should not be freed from within a mixtime sync callback of its (within a non-mixtime sync callback should be fine). So, if you are calling BASS_StreamFree from within a SYNCPROC, what type of sync is it?

cablehead

  • Posts: 315
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #5 on: 8 Sep '08 - 19:03 »
Its a tag sync. I'm not freeing from the callback...

I have a class that creates streams as needed.

Lets say I have a list of presets in front of the user.

Picks one, connects...playing fine.

Now the user clicks on another station/preset while the first is playing. I Free the playing stream and spawn another stream for the new channel. If the tags are updating...crash.

Maybe the syncs are not clearing from the first stream on Stream_Free? (because I recreate the syncs for stream2)

This can get pretty kinky when a user clicks to connect....the stream is attempting to connect...hasn't reached IsActivePlaying yet...and the user says screw it...and clicks a different preset....What is the correct way to dump the first non-connected stream in this case?

radio42

  • Posts: 4573
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #6 on: 8 Sep '08 - 22:41 »
Hmm, that sounds strange. Sorry for a couple of more questions, but it might help to nail down where the actual problem is:

a) Can you please post some of your code on:
    - how you stop and free the 'previous' stream
    - how you connect to a new URL stream
    - how you setup your sync's
    - how you get the tags to display

b) Have you tried the NetRadio samples (both the C# one as well as the precompiled BASS one)?

c) Does this always happen or only at a certain timing or with certain URLs?

cablehead

  • Posts: 315
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #7 on: 9 Sep '08 - 01:00 »
The connect and syncs are exactly the code used in Bass.NET NetRadio example.

To start another stream I just call Stream_Free if activePlaying or stalled on the first one...and create another instance of the class to connect to stream 2.

The labels are updated from an event from my class to the caller via a Dictionary<"Artist",tagInfo.Artist)

Never a problem, unless the sync is "busy"...and I try to free it and create another instance.

I did get around this with a global flag....a new stream cannot be created until the labels are updated.

Should I be calling Channel_Stop before the Free?


Chris

  • Posts: 1808
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #8 on: 9 Sep '08 - 08:40 »
hi
 try to remove the sync...e.g
  BASS_ChannelRemoveSync.......
  BASS_StreamFree ......

Chris

radio42

  • Posts: 4573
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #9 on: 9 Sep '08 - 10:02 »
I guess, that this is a typical multi-threading issue.
The original samples actually didn't care about this fact.

As the META sync is triggered in a BASS thread and your UI stuff is handled in another thread, the following might happen:
- the sync is being triggered and you are calling BASS_ChannelGetTags to get the pointer to the meta data
- at this point your UI thread frees the underlying stream and thus the tag pointer becomes invalid
- now you evaluate the tag pointer, which became 'invalid', which might result in an access violation

So you are right with your workaround, as you need to 'protect' the stream during the tag evaluation to ensure that the tag pointer stays valid. This can either be done by a global variable or by a mutex (lock-statement).

Ian @ un4seen

  • Administrator
  • Posts: 20393
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #10 on: 9 Sep '08 - 16:17 »
To start another stream I just call Stream_Free if activePlaying or stalled on the first one...and create another instance of the class to connect to stream 2.

The labels are updated from an event from my class to the caller via a Dictionary<"Artist",tagInfo.Artist)

Never a problem, unless the sync is "busy"...and I try to free it and create another instance.

I did get around this with a global flag....a new stream cannot be created until the labels are updated.

Are you calling BASS_ChannelGetTags (or some BASS.Net tag function) in the SYNCPROC but not accessing the returned tag until sometime later? If so, what Bernd says is a possibility (accessing the tag buffer after the stream has been freed). You could try making a copy of the tag straight after the BASS_ChannelGetTags call, and then access (and free) that. It's probably safest to stick with what you are already doing though, and just prevent the stream being freed until you are done with the tag :)

Should I be calling Channel_Stop before the Free?

You can do, but it is not necessary as BASS_StreamFree will stop the stream before freeing it.

cablehead

  • Posts: 315
Re: if (BassTags.BASS_TAG_GetFromURL(Stream, tagInfo))
« Reply #11 on: 9 Sep '08 - 22:30 »
Yep...that was it.

When I Stream_Free it dumps the tag sync...but my event from the proc was still firing with a "disposed" Dictionary.

Thanks for the help people.