Author Topic: BASSMix feature request  (Read 5006 times)

3delite

  • Posts: 904
BASSMix feature request
« on: 25 Aug '12 - 13:08 »
Hi!

I am using the matrix mixing feature for changing the volume of channels and it came to my mind to add a 'fade' feature so that the volume change would be faded.

I would like to suggest a BASSMix function like:

Code: [Select]
BASS_Mixer_ChannelSetMatrixFaded(
    DWORD handle,
    float *matrix,
    float DurationInSeconds
);

So I set this function and it would fade the old matrix to the new one in the specified time interval.

This would mean that changing the volume (and panning) could be made softer (with a very short duration eg. 0.1 secs) and also simplifies implementing a 'fade volume' function as the user makes a selection and I can simply use this selection length with a new matrix to fade the volume of the selection in and out. ::)

Best regards
3delite

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #1 on: 1 Sep '12 - 10:56 »
Any news on this? Or no plans to support this feature?

Ian @ un4seen

  • Administrator
  • Posts: 20425
Re: BASSMix feature request
« Reply #2 on: 3 Sep '12 - 16:53 »
I haven't looked into this yet, but I will do so this week.

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #3 on: 4 Sep '12 - 09:02 »
Ok. Cool!

Thank you!

Ian @ un4seen

  • Administrator
  • Posts: 20425
Re: BASSMix feature request
« Reply #4 on: 6 Sep '12 - 17:28 »
OK. Here's something to try...

   www.un4seen.com/stuff/bassmix.zip

It adds a BASS_Mixer_ChannelSetMatrixEx function that is identical to BASS_Mixer_ChannelSetMatrix except that it has a "time" parameter to specify a period (in seconds) for the channel's current matrix to smoothly transition to the specified matrix.

It seems to be working quite nicely, but it hasn't been tested very much yet, so please report what you find.

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #5 on: 7 Sep '12 - 16:10 »
Thank you! Very cool! :)

Sorry to say this, but doesn't work here as expected.

I have 2 matrixes, a 'from' and a 'to'.
If I set the 'from' channels to 20% (0.2) and the 'to' channels's matrixes to 50% then the resulting file is: there's at the start position I see the volume is set to 20% and it stays there for the time specified (so it does know the proper time) and then suddenly at the specified time end the volume sets to he 'to' matrix's setting. So no fade is happening. But the time is right.

Here's how I'm trying:

Code: [Select]
       BASS_ChannelSetSync(MixerChannel, BASS_SYNC_POS OR BASS_SYNC_MIXTIME, Trunc(BASS_ChannelGetLength(Channel, BASS_POS_BYTE) * StartPosition), @FadeVolumeSync, PFadeVolume);

        BASS_ChannelSetSync(MixerChannel, BASS_SYNC_POS OR BASS_SYNC_MIXTIME, Trunc(BASS_ChannelGetLength(Channel, BASS_POS_BYTE) * EndPosition), @FadeVolumeEndSync,
PFadeVolume);


procedure FadeVolumeSync(handle: HSYNC; channel, data: DWORD; user: Pointer);
begin
    BASS_Mixer_ChannelSetMatrix(PFadeVolumeData(User).Channel, PFadeVolumeData(User).StartMatrixBytesData);
    BASS_Mixer_ChannelSetMatrixEx(PFadeVolumeData(User).Channel, PFadeVolumeData(User).EndMatrixBytesData, PFadeVolumeData(User).Time);
end;

procedure FadeVolumeEndSync(handle: HSYNC; channel, data: DWORD; user: Pointer);
begin
    BASS_Mixer_ChannelSetMatrix(PFadeVolumeData(User).Channel, PFadeVolumeData(User).OriginalMatrixBytesData);
end;

Tryed to set the matrix a little bit after setting the initial matrix (so 2 different sync procs) but no change.

Ian @ un4seen

  • Administrator
  • Posts: 20425
Re: BASSMix feature request
« Reply #6 on: 7 Sep '12 - 17:20 »
That's strange. To investigate what's going on, please confirm the values of the paramters and matrixes that you are using in the code above. As you are using Delphi, I have also now added an updated BASSMIX.PAS file to the package I posted above.

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #7 on: 7 Sep '12 - 21:05 »
Some things are missing from the new BASSMix.pas!

Could not compile my app. becouse:
- BASS_MIXER_FILTER is missing from the BASSMix.pas - What happened to it?
- BASS_Mixer_ChannelSetEnvelope() definition changed, I think wrong (will not compile) it should be:

Code: [Select]
function BASS_Mixer_ChannelSetEnvelope(handle, type_: DWORD; nodes: Pointer; count: DWORD): BOOL; stdcall; external bassmixdll;

'nodes' should be a pointer becouse Delphi doesn't allow this kind of parameter handling (array of nodes won't fit into a BASS_MIXER_NODE record).

Back to the fade issue:

I am doing this so far on a stereo MP3 and want to achieve a fade in effect.

StartMatrixBytesData:
(0.2, 0)
(0, 0.2)

EndMatrixBytesData:
(1, 0)
(0, 1)

The selection is 10 seconds and the effect result is also 10 seconds so the time value is correct.

Result is the following:



You can see on the picture that the StartMatrixBytesData was correctly applyed, and the EndMatrixBytesData is also correctly applyed, just no fade yet. The selection's volume becomes a constant 20%.

OriginalMatrixBytesData is the default matrix which is queryed before setting any matrix by:

Code: [Select]
       //* Store default matrix
        DefaultMatrixBytesData := AllocMem(SourceChannelInfo.chans * SourceChannelInfo.chans * SizeOf(Single));
        BASS_Mixer_ChannelGetMatrix(Channel, DefaultMatrixBytesData);

:-\

If I take out the FadeVolumeEndSync() (so do not restore the original matrix) then the part after the selection becomes what is specified for the BASS_Mixer_ChannelSetMatrixEx() function. So it does become set just instantly after 10  secs.
« Last Edit: 7 Sep '12 - 21:12 by 3delite »

Chris

  • Posts: 1810
Re: BASSMix feature request
« Reply #8 on: 9 Sep '12 - 22:47 »
o other way  for the delphi header (array of nodes)
can be (the same as in Pluginstuff in the bass header)
something like this

Code: [Select]
BASS_MIXER_NODE = record
pos: QWORD;
value: Single;
end;
 PBASS_MIXER_NODE = ^TBASS_MIXER_NODE;
 TBASS_MIXER_NODE = array[0..maxInt div sizeOf(BASS_MIXER_NODE) - 1] of BASS_MIXER_NODE;

function BASS_Mixer_ChannelSetEnvelope(handle, type_: DWORD; nodes: PBASS_MIXER_NODE; count: DWORD): BOOL; stdcall; external bassmixdll;
chris

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #9 on: 10 Sep '12 - 09:29 »
Hmmm... I wouldn't do that!

The size of such a variable (TBASS_MIXER_NODE) would be 2GBs if I calculated it correctly. :)

Trying to define such a variable results a stack overflow.

But thinking about it... ...are you thinking to type-cast a BASS_MIXER_NODE array to PBASS_MIXER_NODE and just use the definition of TBASS_MIXER_NODE for the PBASS_MIXER_NODE type?

...

No, that will not compile:

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var
    Nodes: Array[0..1] of BASS_MIXER_NODE;
begin
    BASS_Mixer_ChannelSetEnvelope(0, 0, PBASS_MIXER_NODE(Nodes), 2);
end;

..and tryed this, will not compile either:

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var
    Nodes: Array[0..1] of BASS_MIXER_NODE;
begin
    BASS_Mixer_ChannelSetEnvelope(0, 0, PBASS_MIXER_NODE(Nodes[0]), 2);
end;

Both give invalid type cast error.

But this compiles, didn't try if it works:

Code: [Select]
type
  // envelope node
  BASS_MIXER_NODE = record
pos: QWORD;
value: Single;
  end;

 PBASS_MIXER_NODE = ^BASS_MIXER_NODE;

procedure TForm1.Button1Click(Sender: TObject);
var
    Nodes: Array[0..1] of BASS_MIXER_NODE;
begin
    BASS_Mixer_ChannelSetEnvelope(0, 0, PBASS_MIXER_NODE(@Nodes), 2);
end;

But this seems more complicated for a programmer then the simple Pointer type. ::)

...

I think I found the best solution:

Code: [Select]
type
  // envelope node
  BASS_MIXER_NODE = record
pos: QWORD;
value: Single;
  end;

 PBASS_MIXER_NODE = ^BASS_MIXER_NODE;

function BASS_Mixer_ChannelSetEnvelope(handle, type_: DWORD; nodes: PBASS_MIXER_NODE; count: DWORD): BOOL; stdcall; external bassmixdll;

procedure TForm1.Button1Click(Sender: TObject);
var
    Nodes: Array[0..1] of BASS_MIXER_NODE;
begin
    BASS_Mixer_ChannelSetEnvelope(0, 0, @Nodes, 2);
end;

You can omit the PBASS_MIXER_NODE when making the call.
« Last Edit: 10 Sep '12 - 11:50 by 3delite »

Ian @ un4seen

  • Administrator
  • Posts: 20425
Re: BASSMix feature request
« Reply #10 on: 10 Sep '12 - 15:07 »
- BASS_MIXER_FILTER is missing from the BASSMix.pas - What happened to it?

The BASS_MIXER_FILTER option was removed in the 2.4.7 release, and was superseded by the BASS_ATTRIB_SRC option. Some details on that can be found in the BASS_Mixer_StreamAddChannel documentation.

I think I found the best solution:

Code: [Select]
PBASS_MIXER_NODE = ^BASS_MIXER_NODE;

function BASS_Mixer_ChannelSetEnvelope(handle, type_: DWORD; nodes: PBASS_MIXER_NODE; count: DWORD): BOOL; stdcall; external bassmixdll;

Thanks, an updated BASSMIX.PAS file with that change is now up in the package above/below.

Regarding the matrix transition/fading issue, I see it now: the matrix transition was only being applied when sample rate conversion was required. Here's an update to correct that...

   www.un4seen.com/stuff/bassmix.zip

Let me know if it still gives you any trouble.

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #11 on: 10 Sep '12 - 15:19 »
Thank you! Seems working perfectly!

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #12 on: 16 Sep '12 - 11:48 »
Ok. The new function works nicely so far. But what about adding options to support not only linear but shaped envelopes?

The linear we've got so far:


But what about:

'Fast':


'Slow':


'Smooth':


Please tell me what do you think?

Pictures taken from AVS Audio Editor.

Ian @ un4seen

  • Administrator
  • Posts: 20425
Re: BASSMix feature request
« Reply #13 on: 17 Sep '12 - 13:48 »
Perhaps you could break the wanted envelope down into a series of smaller linear steps? For example, start the first step and set a BASS_POS_SYNC on the mixer to apply the next step, and then start the next step in the SYNCPROC and set another sync for the next step, etc. Something like this...

Code: [Select]
BASS_ChannelRemoveSync(mixer, matrixsync); // remove an existing sync
BASS_ChannelLock(mixer, TRUE); // lock the mixer (block processing while doing the following)
// generate 1st matrix step here
BASS_Mixer_ChannelSetMatrixEx(mixer, matrix, steptime); // apply it
syncpos=BASS_ChannelGetPosition(mixer, BASS_POS_BYTE|BASS_POS_DECODE) // get current position
+BASS_ChannelSeconds2Bytes(mixer, steptime); // time to next step
matrixsync=BASS_ChannelSetSync(mixer, BASS_SYNC_POS|BASS_SYNC_MIXTIME|BASS_SYNC_ONETIME, syncpos, MatrixSyncProc, 0); // set a sync at the next step
BASS_ChannelLock(mixer, FALSE); // unlock the mixer

...

void CALLBACK MatrixSyncProc(HSYNC handle, DWORD channel, DWORD data, void *user)
{
// generate next matrix step here
BASS_Mixer_ChannelSetMatrixEx(channel, matrix, steptime); // apply it
if (finalstep) return; // no more steps
syncpos=BASS_ChannelGetPosition(channel, BASS_POS_BYTE|BASS_POS_DECODE) // get current position
+BASS_ChannelSeconds2Bytes(channel, steptime); // time to next step
matrixsync=BASS_ChannelSetSync(channel, BASS_SYNC_POS|BASS_SYNC_MIXTIME|BASS_SYNC_ONETIME, syncpos, MatrixSyncProc, 0); // set a sync at the next step
}

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #14 on: 18 Sep '12 - 06:34 »
Seems reasonable... but how densely can I apply the matrixes? Can I set for example for every sample (for stereo for a left/right pair)? I mean can I set the synces per sample?

Or would it be simpler to write an own DSP function for this?

But if I write my own function then BASS will not have this function built in and others can miss it.

My other idea is having this SetMatrixEx() function with an envelope parameter and with a 'spline' envelope (bezier?). This way all 3 requested modes could be achieved with a single development and it would be even more versatile (completely customizable shapes) then with the fixed 3 requested modes.

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #15 on: 21 Sep '12 - 14:22 »
I decided to make my version of fade volume function and made it as a BASS add-on.

Already implemented in MP3 Stream Editor and seems working fine.

So the add-on named 'BASS Fade Volume Shaped Library' is available for everyone.

The function is implemented as a form to set the parameters and a function to set up a DSP on a channel with the parameters.

Note that it is not needed to show the dialog, the parameters can be set by code too.



Download the beta: BASS Fade Volume Shaped Library.zip

Only Delphi headers so far, if anybody would like to make other language header files would be welcome!

Tell me what you think!

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #16 on: 22 Sep '12 - 13:14 »
A little update is available:

  • Fixed effect length
  • Added a flag to specify affected channels

Download in the previous post. :)

3delite

  • Posts: 904
Re: BASSMix feature request
« Reply #17 on: 1 Oct '12 - 21:16 »
There is now an official home page for the lib.: BASS Fade Volume Shaped Library

Updates:

  • there are now included versions both for Win32 and Win64 version builds without the dialog (as suggested by Wishmaster)
  • added a function to query the current parameters the user is editing
  • added a function to get the shape values into a buffer (usable for custom display)

The new version can be downloaded from the home page above.