Author Topic: BASS_ChannelSlideAttribute On a Decode Channel?  (Read 1071 times)

normcook04

  • Posts: 26
After reading a post about Editing an existing Mp3, I wrote a routine
which takes StartSec and EndSec as inputs and generates a new Mp3.

It worked just fine, but I wanted to fade out at the end of the created
Mp3.  I added the code with the FadeBytes but it had no effect.  So
perhaps BASS_ChannelSlideAttribute doesn't work on a decode channel.
Any thoughts?
VB6 Code:
Code: [Select]
FadeBytes = 3000 '3 seconds
 Chan = BASS_StreamCreateFile(0&, StrPtr(InMp3), 0&, 0&, BASS_STREAM_DECODE)
 CLen = BASS_ChannelGetLength(Chan, BASS_POS_BYTE)
 SPos = BASS_ChannelSeconds2Bytes(Chan, StartSec)
 EPos = BASS_ChannelSeconds2Bytes(Chan, EndSec)
 Call BASS_ChannelSetPosition64(Chan, SPos, 0&, BASS_POS_BYTE)
 If EPos > CLen Then EPos = CLen
 CLen = EPos - SPos
 EnChan = BASS_Encode_Start(Chan, LameCmd, 0&, 0&, 0&)
 Do While BASS_ChannelIsActive(Chan)
  Call BASS_ChannelGetData(Chan, Buf(0), 20000)
  CPos = BASS_ChannelGetPosition(Chan, BASS_POS_BYTE)
  If CPos >= EPos - FadeBytes Then Exit Do
  RaiseEvent EncodeProgress(((CPos - SPos) / CLen) * 100)
 Loop
 Call BASS_ChannelSlideAttribute(Chan, BASS_ATTRIB_VOL, -1, FadeBytes)
 Call BASS_Encode_Stop(EnChan)
 Call BASS_StreamFree(Chan)

Ian @ un4seen

  • Administrator
  • Posts: 20389
Re: BASS_ChannelSlideAttribute On a Decode Channel?
« Reply #1 on: 21 Dec '11 - 17:32 »
Yep, the BASS_ATTRIB_VOL attribute (and BASS_ATTRIB_PAN/FREQ) doesn't affect the sample data produced by decoding channels, because it isn't applied until the final mix processing during playback. Instead of that, you could use the BASS_FX add-on's BASS_FX_BFX_VOLUME_ENV effect to apply the fade-out, eg. set an envelope that is at full volume and then fades-out at the end. It could be setup something like this...

Code: [Select]
HFX fx=BASS_ChannelSetFX(stream, BASS_FX_BFX_VOLUME_ENV, 0); // set a BASS_FX_BFX_VOLUME_ENV effect on the stream
BASS_BFX_ENV_NODE nodes[3]={ // the envelope
{0, 1}, // start at full volume
{end-fadelen, 1}, // still at full volume, then fade to...
{end, 0} // silence at the end
};
BASS_BFX_VOLUME_ENV fxparam;
fxparam.lChannel=BASS_BFX_CHANALL;
fxparam.lNodeCount=3;
fxparam.pNodes=nodes;
fxparam.bFollow=1;
BASS_FXSetParameters(fx, fxparam); // apply the parameters

Please see the BASS_FX documentation for details.

Note if you aren't already using BASS_FX, you should add a BASS_FX call in your code (eg. BASS_FX_GetVersion) so that the BASS_FX.DLL gets loaded (otherwise the BASS_ChannelSetFX call will fail).

normcook04

  • Posts: 26
Re: BASS_ChannelSlideAttribute On a Decode Channel?
« Reply #2 on: 22 Dec '11 - 15:42 »
Thanks Ian.  Couldn't get it to work.  Using my code below
the created Mp3 is 3 seconds shorter than expected because
the fadeout routine doesn't work.

I only know a little bit of C, but here's what I'm trying:
This is a portion of the main routine
Code: [Select]
FadeBytes = BASS_ChannelSeconds2Bytes(Chan, 3) '3 second fade
 Do While BASS_ChannelIsActive(Chan)
  Call BASS_ChannelGetData(Chan, Buf(0), 20000)
  CPos = BASS_ChannelGetPosition(Chan, BASS_POS_BYTE)
  If CPos >= EPos - FadeBytes Then Exit Do
  RaiseEvent EncodeProgress(((CPos - SPos) / CLen) * 100)
 Loop
 Call FadeOut(Chan, CPos, CPos + FadeBytes)
 Call BASS_Encode_Stop(EnChan)
 Call BASS_ChannelRemoveSync(Chan, SyncHandle)
 Call BASS_StreamFree(Chan)
And here's my attempt at the fadeout
Code: [Select]
Private Sub FadeOut(Chan As Long, FadeStart As Long, FadeEnd As Long)
 Dim Fx As Long
 Dim FS As Double 'fade start in seconds
 Dim FE As Double 'fade end in seconds
 Dim FL As Double 'fade length in seconds
 Dim FxParam As BASS_BFX_VOLUME_ENV
 Dim EnvNode(0 To 2) As BASS_BFX_ENV_NODE
 Call BASS_FX_GetVersion()
 FS = BASS_ChannelBytes2Seconds(Chan, FadeStart) 'everything to seconds
 FE = BASS_ChannelBytes2Seconds(Chan, FadeEnd)
 FL = BASS_ChannelBytes2Seconds(Chan, FadeEnd - FadeStart)
 Fx = BASS_ChannelSetFX(Chan, BASS_FX_BFX_VOLUME_ENV, 0)
 EnvNode(0).pos = 0
 EnvNode(0).val_ = 1
 EnvNode(1).pos = FE - FL 'which is, I guess, the same as FS
 EnvNode(1).val_ = 1
 EnvNode(2).pos = FE
 EnvNode(2).val_ = 0
 With FxParam
  .lChannel = BASS_BFX_CHANALL
  .lNodeCount = 3
  .pNodes = VarPtr(EnvNode(0))
  .bFollow = 1
 End With
 Call BASS_FXSetParameters(Fx, FxParam)
End Sub
Perhaps you can spot something.

Ian @ un4seen

  • Administrator
  • Posts: 20389
Re: BASS_ChannelSlideAttribute On a Decode Channel?
« Reply #3 on: 22 Dec '11 - 16:29 »
The envelope effect should be set before processing the entire stream, ie. move the "FadeOut" call to before the "While" loop and don't exit the loop until the end is reached. It looks like leaving the loop early is the cause of the "3 seconds shorter than expected" problem.

normcook04

  • Posts: 26
Re: BASS_ChannelSlideAttribute On a Decode Channel?
« Reply #4 on: 22 Dec '11 - 18:47 »
Wow - that did it.  Works perfectly.  Many thanks.

Code: [Select]

 '   EPos is the end byte position
 FadeBytes = BASS_ChannelSeconds2Bytes(Chan, 3) '3 second fade
 Call FadeOut(Chan, EPos - FadeBytes, EPos)
 Do While BASS_ChannelIsActive(Chan)
  Call BASS_ChannelGetData(Chan, Buf(0), 20000)
  CPos = BASS_ChannelGetPosition(Chan, BASS_POS_BYTE)
  If CPos >= EPos Then Exit Do
  RaiseEvent EncodeProgress(((CPos - SPos) / CLen) * 100)
 Loop