21 May '13 - 17:22 *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Pages: [1]
  Reply  |  Print  
Author Topic: ASIO and BassVis  (Read 911 times)
diystar
Posts: 23


« on: 9 Apr '12 - 10:12 »
Reply with quoteQuote

When i use ASIO and BassVis at the same time, the music becomes fast and has some noise, how can I avoid it?
When running xmplay with ASIO and xmp-WaVis, the same thing does not appear.
Logged
Emil Weiss
Posts: 107


« Reply #1 on: 9 Apr '12 - 19:09 »
Reply with quoteQuote

When i use ASIO and BassVis at the same time, the music becomes fast and has some noise, how can I avoid it?
When running xmplay with ASIO and xmp-WaVis, the same thing does not appear.

I can not reproduce..

greets
Logged
diystar
Posts: 23


« Reply #2 on: 10 Apr '12 - 05:11 »
Reply with quoteQuote

When i use ASIO and BassVis at the same time, the music becomes fast and has some noise, how can I avoid it?
When running xmplay with ASIO and xmp-WaVis, the same thing does not appear.

I can not reproduce..

greets
I use built-in sound card and ASIO4ALL soft driver.
Logged
Ian @ un4seen
Administrator
Posts: 15258


« Reply #3 on: 10 Apr '12 - 18:01 »
Reply with quoteQuote

When i use ASIO and BassVis at the same time, the music becomes fast and has some noise, how can I avoid it?

Are you using the same handle in your ASIOPROC's BASS_ChannelGetData call and in the BassVis calls? If so, the problem will be that the data taken by the vis stuff will then not be available to the ASIOPROC, ie. the output will skip some data and sound fast. To avoid that, you will need to give the vis a copy of the data that the ASIOPROC receives. That could be done via a custom stream, something like this...

HSTREAM visstream; // vis stream handle
void *visbuf=NULL; // buffer for data to feed the vis stream
DWORD visbuflen=0; // buffer length
DWORD visbuffill=0; // current fill level

...

visstream=BASS_StreamCreate(rate, chans, BASS_SAMPLE_FLOAT|BASS_STREAM_DECODE, VisStreamProc, NULL); // create a custom stream with the same format as the ASIO output

...

DWORD CALLBACK VisStreamProc(HSTREAM handle, void *buf, DWORD len, void *user)
{
if (len>visbuffill) len=visbuffill; // limit it to amount available in the vis buffer
memcpy(buf, visbuf, len); // copy the data from the vis buffer
return len;
}

DWORD CALLBACK AsioProc(BOOL input, DWORD channel, void *buf, DWORD len, void *user)
{
DWORD c=BASS_ChannelGetData(decoder, buf, len); // decode some data
if (c==-1) c=0; // an error, no data
if (visbuflen<c) visbuf=realloc(visbuf, visbuflen=c); // enlarge the vis buffer
memcpy(visbuf, buf, c); // copy the data to the vis buffer
visbuffill=c;
return c;
}

You would then use the "visstream" handle in the vis function calls. To be safe, a lock (eg. critical section) should really be added around the vis buffer stuff in the VisStreamProc and AsioProc functions.

Note that the update rate of the vis will be determined by the ASIO buffer length, as that determines how often new data is placed in the vis buffer.
Logged
diystar
Posts: 23


« Reply #4 on: 11 Apr '12 - 05:05 »
Reply with quoteQuote

Are you using the same handle in your ASIOPROC's BASS_ChannelGetData call and in the BassVis calls? If so, the problem will be that the data taken by the vis stuff will then not be available to the ASIOPROC, ie. the output will skip some data and sound fast. To avoid that, you will need to give the vis a copy of the data that the ASIOPROC receives. That could be done via a custom stream, something like this...

I use delphi6. And the bassvis has no CALLBACK function, it only has the function:
BASSVIS_RenderChannel(@mVisParam, Stream);

When i use the following code, the same thing appears:
procedure TMainForm.TimerFFTTimer(Sender: TObject);
begin
  ...
  BASS_ChannelGetData(Stream, @FFTData, BASS_DATA_FFT1024);
  ...
end
« Last Edit: 11 Apr '12 - 12:05 by diystar » Logged
Emil Weiss
Posts: 107


« Reply #5 on: 11 Apr '12 - 10:52 »
Reply with quoteQuote

procedure TMainForm.TimerFFTTimer(Sender: TObject);
begin
  ...
  BASS_ChannelGetData(Stream, @FFTData, BASS_DATA_FFT1024);
  ...
end

Why your use own fft Data for Winamp Plugin? I have no specified function for Winamp 
BassVis do this for you with

BASSVIS_RenderChannel(@mVisParam, Stream);

DO NOT USE THIS IN A TIMER OR SYNPROC.. only one call after BASSVIS_ExecutePlugin.
your timer function has no effect. (only for Sonique and Aimp Plugin) with

BASSVIS_AIMP2VIS_RenderStreamToDC
BASSVIS_SONIQUEVIS_RenderStreamToDC

for that use Messages instead of Timer see Sample2.
procedure TfrmMain.RenderProc(var Msg: TMessage);

greets
Logged
diystar
Posts: 23


« Reply #6 on: 11 Apr '12 - 11:33 »
Reply with quoteQuote

Why your use own fft Data for Winamp Plugin?
I didn't run bassvis when i used procedure TimerFFTTimer().
« Last Edit: 12 Apr '12 - 05:14 by diystar » Logged
Ian @ un4seen
Administrator
Posts: 15258


« Reply #7 on: 11 Apr '12 - 16:16 »
Reply with quoteQuote

And the bassvis has no CALLBACK function, it only has the function:
BASSVIS_RenderChannel(@mVisParam, Stream);

Yes, that is the call that you would use the "visstream" handle in.
Logged
diystar
Posts: 23


« Reply #8 on: 12 Apr '12 - 04:56 »
Reply with quoteQuote

Yes, that is the call that you would use the "visstream" handle in.
Thx. I will try it.
« Last Edit: 12 Apr '12 - 08:23 by diystar » Logged
diystar
Posts: 23


« Reply #9 on: 12 Apr '12 - 10:34 »
Reply with quoteQuote

HSTREAM visstream; // vis stream handle
void *visbuf=NULL; // buffer for data to feed the vis stream
DWORD visbuflen=0; // buffer length
DWORD visbuffill=0; // current fill level

...

visstream=BASS_StreamCreate(rate, chans, BASS_SAMPLE_FLOAT|BASS_STREAM_DECODE, VisStreamProc, NULL); // create a custom stream with the same format as the ASIO output

...

DWORD CALLBACK VisStreamProc(HSTREAM handle, void *buf, DWORD len, void *user)
{
if (len>visbuffill) len=visbuffill; // limit it to amount available in the vis buffer
memcpy(buf, visbuf, len); // copy the data from the vis buffer
return len;
}

DWORD CALLBACK AsioProc(BOOL input, DWORD channel, void *buf, DWORD len, void *user)
{
DWORD c=BASS_ChannelGetData(decoder, buf, len); // decode some data
if (c==-1) c=0; // an error, no data
if (visbuflen<c) visbuf=realloc(visbuf, visbuflen=c); // enlarge the vis buffer
memcpy(visbuf, buf, c); // copy the data to the vis buffer
visbuffill=c;
return c;
}
Who can translate it to delphi 6 code?
Logged
Emil Weiss
Posts: 107


« Reply #10 on: 12 Apr '12 - 11:48 »
Reply with quoteQuote

create a simple sample for me with YOUR problem and i will check it here on Win7 with latest BassVis do.
translate of this code has no effect for you.

Mediaportal used ASIO with BassVis without problem
Helium Music Manager used ASIO with BassVis without problem

so i have no idea what your do.

greets
« Last Edit: 12 Apr '12 - 12:02 by Emil Weiss » Logged
diystar
Posts: 23


« Reply #11 on: 13 Apr '12 - 03:22 »
Reply with quoteQuote

translate of this code has no effect for you.
The code by Ian@un4seen has solved the problem.

« Last Edit: 13 Apr '12 - 10:02 by diystar » Logged
diystar
Posts: 23


« Reply #12 on: 13 Apr '12 - 04:50 »
Reply with quoteQuote

The delphi code:
 visstream     : HSTREAM;
  visbuf:Pointer=nil;
  visbuflen:DWORD=0;
  visbuffill:DWORD=0;

...

  BASS_ChannelGetInfo(Stream, ChanInfo);
  visstream:=BASS_StreamCreate(ChanInfo.freq, ChanInfo.chans, BASS_SAMPLE_FLOAT or BASS_STREAM_DECODE, VisStreamProc, nil);

...

function VisStreamProc(handle: HSTREAM; buf: Pointer; len: DWORD; user: Pointer): DWORD; stdcall;
begin
  if len>visbuffill then len:=visbuffill;
  CopyMemory(buf,visbuf,len);
  Result:=len;
end;

function AsioProc(input: BOOL; channel: DWORD; buf: Pointer; length: DWORD; user: Pointer): DWORD; stdcall;
var
  c: dword;
begin
  c := Bass_ChannelGetData(DWORD(user), buf, length);
  if c = DWORD(-1) then c := 0;
  if visbuflen<c then
  begin
    visbuflen:=c;
    GetMem(visbuf, visbuflen);
  end;
  CopyMemory(visbuf,buf,c);
  visbuffill:=c;
  Result := c;
end;
When and where can i use FreeMem(visbuf)?
« Last Edit: 13 Apr '12 - 10:15 by diystar » Logged
Emil Weiss
Posts: 107


« Reply #13 on: 13 Apr '12 - 12:46 »
Reply with quoteQuote

translate of this code has no effect for you.
The code by Ian@un4seen has solved the problem.



Good
then I saved my work Smiley

greets
Logged
Ian @ un4seen
Administrator
Posts: 15258


« Reply #14 on: 13 Apr '12 - 15:41 »
Reply with quoteQuote

When and where can i use FreeMem(visbuf)?

The buffer can be reused multiple times, ie. there is no need to free it and reallocate it each time you stop/start ASIO output. So you can leave freeing it until the app closes, perhaps in your FormDestroy function.
Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines