20 May '13 - 20:02 *
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: Drop-outs after fading (Playing next song)  (Read 634 times)
Ops2011
Posts: 40


« on: 23 Jul '12 - 10:30 »
Reply with quoteQuote

I use some standard calls to the BASS_StreamCreateFile. Initialized for two players. Using the BASS_SAMPLE_FLOAT flag. Using the Compressor and Damp, but sometimes whiteout these. 
The fade-in works perfect but sometimes after an fade-in the sound drops to zero and move back to full sound. It's not the same sound what you hear if the real Fade-in occurs.
When this drop-out occurs then if i played the song again everything goes fine. So the mp3 is not damage.
I notice that this fault not always occurs but sometimes. Difficult to trace this fault.
Is this a common problem and can i solved it? Note: I always stream form a local drive, not from network. (I know that network is sometimes slower)
Thank's in advanced. Help help help Smiley
Regards,
Logged
Chris
Posts: 1505


« Reply #1 on: 23 Jul '12 - 10:57 »
Reply with quoteQuote

Without seeing a Portion of your code how your Fadeout is develpope is no help possible
Chris
Logged
Ops2011
Posts: 40


« Reply #2 on: 23 Jul '12 - 12:20 »
Reply with quoteQuote

Little bit of code. Fadein and fadeout seems to be good.
This is not the problem , i think.
procedure TfrmJukebox.CheckPlayerLeft(Sender: TObject);
var
  ChannelState: Cardinal;
  CPLMusicPositionLeftMS: Cardinal;
  //CPLMusicPositionRightMS: Cardinal;
  CPLFadeTimeTriggerLeftMS: Cardinal;
  //CPLFadeTimeTriggerRightMS: Cardinal;
  LeftFadeIn, LeftFadeOut: WideString;

  procedure CheckFading;
  begin
    { Fade Controle: CrossFade Moment! }
    if (CPLMusicPositionLeftMS >= CPLFadeTimeTriggerLeftMS) and (AutoAfspelen) then begin
      AddLog(_ReportLog, '  > CrossVisualStart: ' + IntToStr(CPLMusicPositionLeftMS)); // FormatTijd
      CrossVisual.Start(BASS_DoubleToCardinal(PlayerLeft.EndPoint) - CPLMusicPositionLeftMS);
      LeftPlayerInfo.CrossFadeMode := clfInitCrossFade;
      {Label3.Caption := IntToStr(MusicPositionLeftMS);}
    end;
  end;

  procedure InitCrossFade;
  begin
    if (CrossFadeTimePoint > 0) then begin
      LeftPlayerInfo.CrossFadeMode := clfCrossFadeOut;
      //AddLog(_ReportLog, 'InitCrossFade (LeftPlayerInfo.clfCrossFadeOut) : ' + IntToStr(CrossFadeTimePoint));
    end else begin
      // Speel direct het volgende nummer!
      LeftPlayerInfo.CrossFadeMode := clfPending;
      RightPlayerInfo.CrossFadeMode := clfCrossFadeIn;
      //AddLog(_ReportLog, 'InitCrossFade (LeftPlayerInfo.clfPending) : ' + IntToStr(CrossFadeTimePoint));
      PlayerLeft.BASS_Stop;
    end;
  end;

  procedure CrossFadeStart;
  var
    FadeOutStart, FadeOutBreak, FadeOutPointer: Cardinal;
    {FadeInStart,}
    FadeInDelay, FadeInPointer: Cardinal;
    MusicOffset: Cardinal;
  begin
    { Start en Break FadeOut berekenen }
    FadeOutStart := Round(CrossFadeTimePoint * (CrossFadeChannelOut / 100));
    FadeOutBreak := Round(CrossFadeTimePoint * (CrossFadeChannelBreak / 100));
    { Het moment dat FadeOut mag beginnen }
    FadeOutPointer := BASS_DoubleToCardinal(PlayerLeft.EndPoint) - (CrossFadeTimePoint - FadeOutStart);

    { Start en Delay FadeIn berekenen }
    //FadeInStart := Round(CrossFadeTimePoint * (CrossFadeChannelIn / 100));
    FadeInDelay := Round(CrossFadeTimePoint * (CrossFadeChannelDelay / 100));
    { Het moment dat FadeIn mag beginnen }
    // FadeInPointer := (CrossFadeTimePoint - FadeInDelay); OUDE!
    FadeInPointer := BASS_DoubleToCardinal(PlayerLeft.EndPoint) - (CrossFadeTimePoint - FadeInDelay);

    { Positie nummer Rechts uitlezen }
    MusicOffSet := BASS_DoubleToCardinal(PlayerLeft.EndPoint) - CPLMusicPositionLeftMS;

    { FadeIn Berekenen }
    {
    if not PlayerSLIDING(spRight) then begin
      LabelLeftFadeIn.Caption := 'FadeIn: ' + IntToStr(FadeInPointer) + ' >= ' + IntToStr(MusicOffset);
      if (FadeInPointer >= MusicOffset) or (FadeInDelay = 0) then begin
        RightPlayerInfo.CrossFadeMode := clfCrossFadeIn;
      end;
    end;
    }
    if not PlayerSLIDING(spRight) then begin
      LeftFadeIn := 'FadeIn: ' + IntToStr(CPLMusicPositionLeftMS) + ' > ' + IntToStr(FadeInPointer);
      if (CPLMusicPositionLeftMS > FadeInPointer) or (FadeInDelay = 0) then begin
        AddLog(_ReportLog, 'CrossFadeStart (RightPlayerInfo.clfCrossFadeIn) : ' + LeftFadeIn);
        RightPlayerInfo.CrossFadeMode := clfCrossFadeIn;
      end;
    end;

    { FadeOut Berekenen }
    if not PlayerSLIDING(spLeft) then begin
      LeftFadeOut := 'FadeOut: ' + IntToStr(CPLMusicPositionLeftMS) + ' > ' + IntToStr(FadeOutPointer);
      if (CPLMusicPositionLeftMS > FadeOutPointer) then begin
        AddLog(_ReportLog, 'CrossFadeStart (ChannelSlideAttribute.Left) : ' + LeftFadeOut);
        if (CrossFadeChannelOut <> CrossFadeChannelBreak) then begin
          { Fade tot einde nummer en FREE Stream }
          BASS_ChannelSlideAttribute(PlayerLeft.Stream, BASS_ATTRIB_VOL, -1, MusicOffset - (CrossFadeTimePoint - FadeOutBreak));
        end else begin
          { Direct stoppen }
          PlayerLeft.BASS_Stop;
        end;
      end;
    end;

    { Einde Berekenen }
    if (ChannelState = BASS_ACTIVE_STOPPED) then begin
      LeftPlayerInfo.CrossFadeMode := clfPending;
    end;
    if (PlayerSLIDING(spLeft) and PlayerSLIDING(spRight)) then begin
      LeftPlayerInfo.CrossFadeMode := clfPending;
    end;
  end;

  procedure CrossFadeIn;
  var
    FadeIn, FadeDelay: Cardinal;
  begin
    if (CrossFadeTimePoint > 0) then begin

      FadeIn := Round(CrossFadeTimePoint * (CrossFadeChannelIn / 100)); { Klopt }
      FadeDelay := Round(CrossFadeTimePoint * (CrossFadeChannelDelay / 100)); { Klopt }

      if (CrossFadeChannelIn <> CrossFadeChannelDelay) then begin
        PlayerLeft.BASS_SetVolume(0);
        BASS_ChannelSlideAttribute(PlayerLeft.Stream, BASS_ATTRIB_VOL, SetLeftPlayerVolume, (FadeIn - FadeDelay));
        //AddLog(_ReportLog, 'CrossFadeIn (PlayerLeft.ChannelSlideAttribute) : ' + IntToStr(FadeIn - FadeDelay));
      end;
      LeftPlayerInfo.CrossFadeMode := clfCheckFading;
      PlayerLeft.BASS_Play;
      CheckAutoEffectPlay(LeftPlayerInfo.MusicInfo);

    end else begin
      LeftPlayerInfo.CrossFadeMode := clfCheckFading;
      //AddLog(_ReportLog, 'CrossFadeIn (PlayerLeft.PLAY) : ' + IntToStr(CrossFadeTimePoint));
      PlayerLeft.BASS_Play;
      CheckAutoEffectPlay(LeftPlayerInfo.MusicInfo);
    end;
  end;

  { Basisversie, ik weet nog niet hoe verder! }
  procedure ManualFade;
  var
    //Eduard,
    FadeOutTime,
    FadeInTime: Cardinal;
  begin
    { Rechts FadeOut en FREE Stream }
    FadeOutTime := (CrossFadeTimePoint) - Round(CrossFadeTimePoint * (CrossFadeChannelOut / 100));
    BASS_ChannelSlideAttribute(PlayerRight.Stream, BASS_ATTRIB_VOL, -1, FadeOutTime);

    { Links Volume op 0 zetten en Infaden }
    PlayerLeft.BASS_SetVolume(0);
    FadeInTime := Round(CrossFadeTimePoint * (CrossFadeChannelIn / 100));
    BASS_ChannelSlideAttribute(PlayerLeft.Stream, BASS_ATTRIB_VOL, SetLeftPlayerVolume, FadeInTime);

    LeftPlayerInfo.CrossFadeMode := clfCheckFading;
    PlayerLeft.BASS_Play;
    CheckAutoEffectPlay(LeftPlayerInfo.MusicInfo);

    { Afronden }
    //Eduard := FadeInTime - FadeOutTime; // IS DIT BETER? EDUARD ALS FADEIN GEBRUIKEN?
    RightPlayerInfo.CrossFadeMode := clfPending;
  end;

  procedure Pending;
  begin
    if (ChannelState = BASS_ACTIVE_STOPPED) then begin
      { Nieuw nummer laden en resetten }
      AddLog(_ReportLog, '  > Pending finished: FindAutoLinks');
      LeftPlayerInfo.CrossFadeMode := clfCheckFading;
      FindAutoLinks(Sender);
      UpdateInfoBlok;
    end;
  end;

begin
  { Berekenen variabelen, Cardinal? }
  CPLMusicPositionLeftMS := BASS_DoubleToCardinal(PlayerLeft.BASS_Bytes2Seconds(PlayerLeft.BASS_GetPosition)); {!}
  CPLFadeTimeTriggerLeftMS := (BASS_DoubleToCardinal(PlayerLeft.EndPoint) - CrossFadeTimePoint); {!}
  //Label5.Caption := IntToStr(MusicPositionLeftMS);
  //Label6.Caption := IntToStr(FadeTimeTriggerLeftMS) + ' > ' + FormatTijd(FadeTimeTriggerLeftMS);
  { Idem Right }
  //CPLMusicPositionRightMS := BASS_DoubleToCardinal(PlayerRight.BASS_Bytes2Seconds(PlayerRight.BASS_GetPosition)); {!}
  //CPLFadeTimeTriggerRightMS := (BASS_DoubleToCardinal(PlayerRight.EndPoint) - CrossFadeTimePoint); {!}
  //Label7.Caption := IntToStr(MusicPositionRightMS);
  //Label8.Caption := IntToStr(FadeTimeTriggerRightMS) + ' > ' + FormatTijd(FadeTimeTriggerRightMS);

  { Visuele weergave zoals Slider en LedSegment }
  ChannelState := BASS_ChannelIsActive(PlayerLeft.Stream);
  case ChannelState of
    BASS_ACTIVE_PLAYING: begin
      { Scrollbalk wordt niet aangeraakt dus we mogen verder }
      if (LeftPlayerInfo.ScrollCode in [scEndScroll]) then begin
        { Counters en Scrollbalk bijhouden }
        UpdateTijdLoopLeft(CPLMusicPositionLeftMS);
        UpdateCountDownLeft(PlayerLeft.TotalPlayingTime, PlayerLeft.BASS_Seconds2Bytes(PlayerLeft.EndPoint), CPLMusicPositionLeftMS);
        ScrollbarLeft.Position := CPLMusicPositionLeftMS;
      end;
    end;
    BASS_ACTIVE_STOPPED: begin
      {}
    end;
  end;

  { Volgens Crossover instellingen }
  case LeftPlayerInfo.CrossFadeMode of
    clfCheckFading        : CheckFading;
    clfInitCrossFade      : InitCrossFade;
    clfCrossFadeOut       : CrossFadeStart;
    clfCrossFadeIn        : CrossFadeIn;
    clfManualFade         : ManualFade;
    clfPending            : Pending;
  end; {Case}

  {Label1.Caption := GetEnumName(TypeInfo(TCrossFadeMode), Integer(LeftPlayerInfo.CrossFadeMode));}
end;
Logged
Chris
Posts: 1505


« Reply #3 on: 23 Jul '12 - 14:35 »
Reply with quoteQuote

Are you doing the Fadeing Stuff inside a Timer ??
Chris
Logged
Ops2011
Posts: 40


« Reply #4 on: 23 Jul '12 - 16:20 »
Reply with quoteQuote

Are you doing the Fadeing Stuff inside a Timer ??
Chris

Yes all is Timer. That's why i'am use case label for progress?
Every step is to the next step.
so see my code.
Logged
Chris
Posts: 1505


« Reply #5 on: 23 Jul '12 - 16:42 »
Reply with quoteQuote

Thats the problem! a Standart Timer is not accurate.
To be on the safe and fast Side its better to use BASS_ChannelSetSync and as param BASS_SYNC_SLIDE.
To be here also on the safe side do not put the Graphic/Canvas Stuff in the Callback just do it inside the callback with a Send/Post Message
Chris

Logged
Ian @ un4seen
Administrator
Posts: 15253


« Reply #6 on: 23 Jul '12 - 16:56 »
Reply with quoteQuote

        PlayerLeft.BASS_SetVolume(0);
        BASS_ChannelSlideAttribute(PlayerLeft.Stream, BASS_ATTRIB_VOL, SetLeftPlayerVolume, (FadeIn - FadeDelay));
...
    PlayerLeft.BASS_SetVolume(0);
    FadeInTime := Round(CrossFadeTimePoint * (CrossFadeChannelIn / 100));
    BASS_ChannelSlideAttribute(PlayerLeft.Stream, BASS_ATTRIB_VOL, SetLeftPlayerVolume, FadeInTime);

Those BASS_SetVolume calls look like they could be a problem. BASS_SetVolume sets the device's volume level, while BASS_ChannelSlideAttribute deals with a particular BASS channel's volume level. To have BASS_ChannelSlideAttribute fade-in a BASS channel, BASS_ChannelSetAttribute should be used (instead of BASS_SetVolume) to start the volume level at 0...

        BASS_ChannelSetAttribute(PlayerLeft.Stream, BASS_ATTRIB_VOL, 0);
        BASS_ChannelSlideAttribute(PlayerLeft.Stream, BASS_ATTRIB_VOL, SetLeftPlayerVolume, (FadeIn - FadeDelay));
...
    BASS_ChannelSetAttribute(PlayerLeft.Stream, BASS_ATTRIB_VOL, 0);
    FadeInTime := Round(CrossFadeTimePoint * (CrossFadeChannelIn / 100));
    BASS_ChannelSlideAttribute(PlayerLeft.Stream, BASS_ATTRIB_VOL, SetLeftPlayerVolume, FadeInTime);
Logged
Ops2011
Posts: 40


« Reply #7 on: 24 Jul '12 - 03:02 »
Reply with quoteQuote

Thanks Chris and Ian.

I think that the Timer works great. I uses some Hires Timers.

What about Ian, great. This is the only 'volume' fault. So this must be it?
I give it a go and hope's this adjustment works. It take some time to check this!

Greetings...
Logged
Ops2011
Posts: 40


« Reply #8 on: 24 Jul '12 - 09:00 »
Reply with quoteQuote

I adjusted  BASS_SetVolume(0) > BASS_ChannelSetAttribute(Stream, BASS_ATTRIB_VOL, 0)
The problem occurs again.

I noticed that my computer is using a lot of resources (like calculating .par files) when this occurs (I notice now and had no idea before). But only at the start of the music. If the music continued to play, no problem. 
Is this a simple processor fault? When starting a song the BASS engine has not enough resources to start right away?

Do you have a solution to fix this or is it just the way it is?
I use: BASS_CONFIG_UPDATETHREADS = 1; (I have a dual processor so, setting to 2?) or more?
Can i use BASS_CONFIG_BUFFER to improve?
Or is this down the road and play your songs without running 'heavy' background programs?

Hope the explanation is clear and free me from further searching.     

Thanks in advanced.
Eduard.



Logged
Ian @ un4seen
Administrator
Posts: 15253


« Reply #9 on: 24 Jul '12 - 17:07 »
Reply with quoteQuote

Update threads (BASS_CONFIG_UPDATETHREADS) won't affect attribute slides, and nor will the buffer length (BASS_CONFIG_BUFFER) in the case of BASS_ATTRIB_VOL; it does affect some others (noted in the docs). Attribute slides are applied by the sync thread (the same thread that calls non-mixtime SYNCPROCs), which runs at above normal priority, so they shouldn't be affected too badly when the system is busy, unless it is even higher priority threads that are busy (or the sync thread!).

To get a better idea of what the problem is, perhaps you can make a recording of it? Please also eliminate anything else from your tests, eg. if the problem is only affecting fading-in then don't also fade-out another track.
Logged
Ops2011
Posts: 40


« Reply #10 on: 25 Jul '12 - 09:05 »
Reply with quoteQuote

I take another good look at the code because maybe something overlooked.
Thanks anyway.
Logged
Ops2011
Posts: 40


« Reply #11 on: 30 Jul '12 - 11:33 »
Reply with quoteQuote

The problem was the Timer, every time the processor is overloaded the timer reloads. That was a fault in my source i noticed. I put it all together and followed Chris his idea. I focused to much on Timer calls. Thank you. See here some results: ( Just left only for view )

{==============================================================================}
{== ChannelSetSync of the type BASS_SYNC_POS (SyncHandle PlayerLeft) ==========}
{==============================================================================}

procedure LeftFadeTimeStart(SyncHandle: HSYNC; Channel, data, user: DWORD); stdcall;
begin
  aSyncBoolLeft.hSyncFadeTimeStart := True;
  frmJukebox.LeftFadeTimeStartProc;
end;

procedure LeftStartFadeIn(SyncHandle: HSYNC; Channel, data, user: DWORD); stdcall;
begin
  aSyncBoolLeft.hSyncStartFadeIn := True;
  frmJukebox.LeftStartFadeInProc;
end;

procedure LeftStartFadeOut(SyncHandle: HSYNC; Channel, data, user: DWORD); stdcall;
begin
  aSyncBoolLeft.hSyncStartFadeOut := True;
  frmJukebox.LeftStartFadeOutProc;
end;

procedure LeftAutoCue(SyncHandle: HSYNC; Channel, data, user: DWORD); stdcall;
begin
  aSyncBoolLeft.hSyncAutoCue := True;
  frmJukebox.LeftAutoCueProc;
end;

procedure LeftEndStream(SyncHandle: HSYNC; Channel, data, user: DWORD); stdcall;
begin
  aSyncBoolLeft.hSyncEndStream := True;
  frmJukebox.LeftEndStreamProc;
end;
 

And with a little bit help from WndProc:

procedure TfrmJukebox.WndProc(var Msg: TMessage);
begin
  inherited;
  if Msg.Msg = WM_INFO_UPDATE then
    case msg.WParam of
      EJB_MSG_INIT_PLAYER_LEFT: InitPlayerLeft;
        // SendMessage(Handle, WM_INFO_UPDATE, EJB_MSG_INIT_PLAYER_LEFT, 0);
      EJB_MSG_INIT_PLAYER_RIGHT: InitPlayerRight;
        // SendMessage(Handle, WM_INFO_UPDATE, EJB_MSG_INIT_PLAYER_RIGHT, 0);
      EJB_MSG_NOTIFY_NACK_LEFT: MessagePlayerNotifyNack(PlayerLeft, msg.LParam);
        // SendMessage(Handle, WM_INFO_UPDATE, EJB_MSG_NOTIFY_NACK_LEFT, ErrorGetCode);
      EJB_MSG_NOTIFY_NACK_RIGHT: MessagePlayerNotifyNack(PlayerRight, msg.LParam);
        // SendMessage(Handle, WM_INFO_UPDATE, EJB_MSG_NOTIFY_NACK_RIGHT, ErrorGetCode);
      EJB_MSG_UPDATE_STATUS_PANELS: UpdateStatusPanels;
        // SendMessage(Handle, WM_INFO_UPDATE, EJB_MSG_UPDATE_STATUS_PANELS, 0);
      EJB_MSG_MARGUEE_INFO_LEFT: MargueeInfoLinks.Items[0].Text := CreateMargueeInfo(LeftPlayerInfo.MusicInfo);
        // SendMessage(Handle, WM_INFO_UPDATE, EJB_MSG_MARGUEE_INFO_LEFT, 0);
      EJB_MSG_MARGUEE_INFO_RIGHT: MargueeInfoRechts.Items[0].Text := CreateMargueeInfo(RightPlayerInfo.MusicInfo);
        // SendMessage(Handle, WM_INFO_UPDATE, EJB_MSG_MARGUEE_INFO_RIGHT, 0);
      EJB_MSG_UPDATE_INFO_BLOCK: UpdateInfoBlok;
        // SendMessage(Handle, WM_INFO_UPDATE, EJB_MSG_CLEAR_PLAYER_LEFT, BoolToInt(ClearInfo));
      EJB_MSG_CLEAR_PLAYER_LEFT: ClearPlayerLeft(IntToBool(msg.LParam));
        // SendMessage(Handle, WM_INFO_UPDATE, EJB_MSG_CLEAR_PLAYER_RIGHT, BoolToInt(ClearInfo));
      EJB_MSG_CLEAR_PLAYER_RIGHT: ClearPlayerRight(IntToBool(msg.LParam));
    end;
end;

Must do the trick to get it all right without failures.

Question: I have some problems to call ShowMessage if in the fade moment a file does not exists? I am very certain that i call this within a Message. But i know that the procedure that i am calling to select the next song is not in the SendMessage WndProc. Like this:

procedure TfrmJukebox.PlayerLeftNotifyNack(ErrorGetCode: Integer); { < Called
begin
  ArtistLeft.Caption := PlayerLeft.PlayBuffer.Filename;
  TitleLeft.Caption := BASSErCodes[ErrorGetCode];
  {MessagePlayerNotifyNack(PlayerLeft, ErrorGetCode); = now Sendmessage}
  SendMessage(Handle, WM_INFO_UPDATE, EJB_MSG_NOTIFY_NACK_LEFT, ErrorGetCode); { Here is Sendmessage }
end;
   

System hangs after notify.

Question II: I use only streams to play music. Is the flag 'BASS_SAMPLE_FLOAT' obsolete? I don't use DECODED channels.

Regards.


 
     
Logged
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.18 | SMF © 2013, Simple Machines