Author Topic: Decoding streams problem  (Read 18606 times)

hukka

  • Posts: 77
Decoding streams problem
« on: 31 Aug '03 - 16:56 »
I'm using Delphi and trying to play a tune simultaneously on two outputs of my soundcard. This requires one decoding stream and two custom streams, one for each output. A buffer is required, to which the decoding is first done and then fed to the custom streams.

Now my problem is that I'm stupid, and don't know how to code it. I have something that kinda works, adapted for some C example that came with BASS (4speaker.c, I think) - but it only works for two songs simultaneously. Trying to play three or more songs = crash.

My code is a mess. I'm not sure I understand how this buffering thing works exactly, so I would like to either someone write the routine for me ;) or help me writing it.

I think the routines should basically consist of a routine that checks the decoding buffer and fills it if necessary, and two callback routines for the custom streams, each calling the buffer updating routine. Help?

hukka

  • Posts: 77
Re: Decoding streams problem
« Reply #1 on: 1 Sep '03 - 15:18 »
It actually seems that the problem I'm having is not the buffering routine, but that BASS will not play the second custom stream for the third song. This seems to only happen when using BASS_SPEAKER flags. In more detail:

I have a Delphi Form with a decoding channel and two custom streams which I initialize using the flags BASS_SPEAKER_FRONT and BASS_SPEAKER_REAR. The STREAMPROCs for these two custom streams are the simplest possible, basically just returning Length so that the streams will keep on playing.

Now, as I create two instances of this Form, the streams will play just as they should without trouble. But when I go on to create a third instance of the Form, what happens is this: custom stream number one plays just as it should, but the second custom stream will only call the STREAMPROC about three to five times, then just STOP calling it. (This is also why my buffering routine failed.) Calling BASS_ChannelIsActive on this second stream will still return BASS_ACTIVE_PLAYING.

Is this a bug in BASS or something wrong with either my drivers or sound card? (SB Live, Windows 2000 SP4)
(To clarify, this only happens when using BASS_SPEAKER flags (which I really need here)).
« Last Edit: 1 Sep '03 - 15:19 by hukka »

Ian @ un4seen

  • Administrator
  • Posts: 26252
Re: Decoding streams problem
« Reply #2 on: 1 Sep '03 - 18:35 »
When you say you create 2 or 3 instances of a form, does that also mean 2 or 3 instances of BASS.DLL?

You can verify whether or not it's a problem with your STREAMPROC by replacing the custom streams with normal file streams - if they play fine, then you know it's a problem with the STREAMPROC.

Also, can you reproduce the problem running 2 copies of the SPEAKERS example?

Regarding the original buffering question, something like this should work (untested though :))...
Code: [Select]
BYTE *buf=0; // decoding buffer
DWORD buflen=0; // buffer length
DWORD writepos,readpos[NO_OF_STREAMS]; // write/read pointers
HSTREAM decoder; // decoding channel

DWORD CALLBACK streamproc(HSTREAM handle, BYTE *buffer, DWORD length, DWORD user)
{
     DWORD pos=readpos[user]+length;
     if (pos>writepos) { // need to decode more data
           int a,o=readpos[0];
           for (a=1;a<NO_OF_STREAMS;a++) if (o>readpos[a]) o=readpos[a];
           if (o) { // discard used data
                 writepos-=o;
                 memmove(buf,buf+o,writepos);
                 for (a=0;a<NO_OF_STREAMS;a++) readpos[a]-=o;
                 pos-=o;
           }
           if (pos>buflen) { // need to enlarge buffer
                 buflen=pos;
                 buf=realloc(buf,buflen);
           }
           // decode upto requested position
           o=BASS_ChannelGetData(decoder,buf+writepos,pos-writepos);
           if (o>0) writepos+=o;
     }
     if (length>writepos-readpos[user]) length=writepos-readpos[user];
     // copy decoded data to stream
     memcpy(buffer,buf+readpos[user],length);
     readpos[user]+=length;
     return length;
}

When you create the custom streams, they all use the same STREAMPROC, but with a different number (0=1st,1=2nd,etc) passed in the user parameter. Before starting playback, reset writepos and all the readpos to 0.

hukka

  • Posts: 77
Re: Decoding streams problem
« Reply #3 on: 1 Sep '03 - 18:56 »
Thanks for the reply, Ian! Also mucho thanks for the code, I'll try it out later. Anyway:

Only one instance of BASS.DLL. The forms with the streams are MDI child forms of a main form that hosts the DLL.

Normal file streams work fine - they're what I was using in my program before, and always worked great.
But I can't see what could be wrong with my STREAMPROCs - at the moment they only contain the line "Result := length;" - the Delphi equivalent of "return(length)".

Tried running three instances of the SPEAKERS example proggy and worked fine for both rear and front outputs.

bigjim

  • Posts: 232
Re: Decoding streams problem
« Reply #4 on: 2 Sep '03 - 03:29 »
Any chance of a look at the code ;D
alex@ingenious.demon.co.uk

But make it quick im back to uni near the end of the month :'(

hukka

  • Posts: 77
Re: Decoding streams problem
« Reply #5 on: 2 Sep '03 - 07:19 »
I made a simple test proggy which creates six custom streams (in groups of two; three for FRONT and three for REAR outputs) and displays when their STREAMPROCs are called.

http://www.hukka.furtopia.org/temp/test.zip
(Executable plus D6 sources)

On my machine, the third group's second STREAMPROC (last checkbox in the test proggy) is called a few times and then not at all anymore, while the two other ones keep on playing as they should.
« Last Edit: 2 Sep '03 - 07:22 by hukka »

hukka

  • Posts: 77
Re: Decoding streams problem
« Reply #6 on: 3 Sep '03 - 09:07 »
I guess I should've tested it more thoroughly - by reducing my soundcard's hardware acceleration to next to none, it seems to work. Also, on Windows 98 SE it seemed to work. So, apparently a driver issue.

[Edit: arrrgghh.. well, with the level of acceleration that low, the speaker assignments do not work! So while now the test doesn't _fail_, it's practically useless as the speaker assignments are ignored. (Also with Creative Mixer's speaker test.) And I'm using the latest drivers for my sound card.]
« Last Edit: 3 Sep '03 - 09:29 by hukka »

Ian @ un4seen

  • Administrator
  • Posts: 26252
Re: Decoding streams problem
« Reply #7 on: 5 Sep '03 - 10:46 »
Are you still having problems with this?

I tried running your test on an SBLive/WinXP system, and it worked fine - all 6 boxes constantly flashed. So, if you're still having trouble, I guess it's either a driver or Win2K issue. I can't remember which drivers I have installed, but DxDiag says this about them:
Code: [Select]
           Driver Name: emu10k1m.sys
        Driver Version: 5.12.0001.3300 (English)
     Driver Attributes: Final Retail
           WHQL Logo'd: n/a
         Date and Size: 6/12/2002 09:46:06, 284288 bytes

hukka

  • Posts: 77
Re: Decoding streams problem
« Reply #8 on: 5 Sep '03 - 13:59 »
Still having that problem, yes. Had a friend try the test on his Win2K/SBLive system, and it failed like on my system. So yeah, probably an Win2K or driver issue.

For myself, I solved it for myself by getting rid of Creative's drivers (I had the latest ones installed, btw) and installing kX drivers (http://kxproject.lugosoft.com/) instead - these drivers give me access to the front and rear outputs as separate audio devices, which works for me.

But there are other people using my program that also use Win2K+SBLive with Creative's drivers - too bad for them, I guess... Anyway, I'd be glad if other SBLive users would try and see if my test proggy works for them, just in case.

bigjim

  • Posts: 232
Re: Decoding streams problem
« Reply #9 on: 5 Sep '03 - 18:08 »
I use the kx drivers myself- and they are getting to the stage in their development where I would recommend that all SB Live / Audigy users use them instead of the inferior creative drivers. :evil:

hukka

  • Posts: 77
Re: Decoding streams problem
« Reply #10 on: 5 Sep '03 - 18:51 »
bigjim: yeah, the kX drivers are really great. I love how they allow to tweak pretty much everything. :o) But I still don't want to force SBLive+W2K users to install these drivers if they want to properly use my software :o/

Ian: in your streamproc example you gave, why are you changing the value of Length near the end of the routine?
Code: [Select]
if (length>writepos-readpos[user]) length=writepos-readpos[user];
Doesn't this just stop the stream from playing as the returned value is not the same as Length was at first? (Hope you understand what I mean. I'm having problems getting the routine to work and I think the problem is around this part of the routine..)

Ian @ un4seen

  • Administrator
  • Posts: 26252
Re: Decoding streams problem
« Reply #11 on: 6 Sep '03 - 13:47 »
Quote
Doesn't this just stop the stream from playing as the returned value is not the same as Length was at first?

Yep, it's so that the custom stream ends when there's no more data left to decode.
« Last Edit: 6 Sep '03 - 13:48 by Ian @ un4seen »

hukka

  • Posts: 77
Re: Decoding streams problem
« Reply #12 on: 6 Sep '03 - 14:35 »
Thanks for your help, Ian. It works perfectly now - I had just left out one crucial line of code.