@@ -2508,99 +2508,29 @@ void CCtrlSamples::OnSustainPointsChanged()
25082508}
25092509
25102510
2511- #define SMPLOOP_ACCURACY 7 // 5%
2512- #define BIDILOOP_ACCURACY 2 // 5%
2513-
2514-
2515- bool MPT_LoopCheck (int sstart0, int sstart1, int send0, int send1)
2516- {
2517- int dse0 = send0 - sstart0;
2518- if ((dse0 < -SMPLOOP_ACCURACY) || (dse0 > SMPLOOP_ACCURACY)) return false ;
2519- int dse1 = send1 - sstart1;
2520- if ((dse1 < -SMPLOOP_ACCURACY) || (dse1 > SMPLOOP_ACCURACY)) return false ;
2521- int dstart = sstart1 - sstart0;
2522- int dend = send1 - send0;
2523- if (!dstart) dstart = dend >> 7 ;
2524- if (!dend) dend = dstart >> 7 ;
2525- if ((dstart ^ dend) < 0 ) return false ;
2526- int delta = dend - dstart;
2527- return ((delta > -SMPLOOP_ACCURACY) && (delta < SMPLOOP_ACCURACY));
2528- }
2529-
2530-
2531- bool MPT_BidiEndCheck (int spos0, int spos1, int spos2)
2532- {
2533- int delta0 = spos1 - spos0;
2534- int delta1 = spos2 - spos1;
2535- int delta2 = spos2 - spos0;
2536- if (!delta0) delta0 = delta1 >> 7 ;
2537- if (!delta1) delta1 = delta0 >> 7 ;
2538- if ((delta1 ^ delta0) < 0 ) return false ;
2539- return ((delta0 >= -1 ) && (delta0 <= 0 ) && (delta1 >= -1 ) && (delta1 <= 0 ) && (delta2 >= -1 ) && (delta2 <= 0 ));
2540- }
2541-
2542-
2543- bool MPT_BidiStartCheck (int spos0, int spos1, int spos2)
2544- {
2545- int delta1 = spos1 - spos0;
2546- int delta0 = spos2 - spos1;
2547- int delta2 = spos2 - spos0;
2548- if (!delta0) delta0 = delta1 >> 7 ;
2549- if (!delta1) delta1 = delta0 >> 7 ;
2550- if ((delta1 ^ delta0) < 0 ) return false ;
2551- return ((delta0 >= -1 ) && (delta0 <= 0 ) && (delta1 > -1 ) && (delta1 <= 0 ) && (delta2 >= -1 ) && (delta2 <= 0 ));
2552- }
2553-
2554-
2555-
25562511void CCtrlSamples::OnVScroll (UINT nCode, UINT, CScrollBar *scrollBar)
25572512{
2558- TCHAR s[256 ];
2513+ TCHAR s[32 ];
25592514 if (IsLocked ()) return ;
25602515 ModSample &sample = m_sndFile.GetSample (m_nSample);
2561- const uint8 *pSample = mpt::byte_cast<const uint8 *>(sample.sampleb ());
2562- const uint32 inc = sample.GetBytesPerSample ();
2563- SmpLength i;
2564- int pos;
2516+ const bool moveLoop = CMainFrame::GetInputHandler ()->CtrlPressed ();
25652517 bool redraw = false ;
25662518 static CScrollBar *lastScrollbar = nullptr ;
25672519
25682520 LockControls ();
2569- if ((!sample.nLength ) || (!pSample)) goto NoSample;
2570- if (sample.uFlags [CHN_16BIT])
2571- {
2572- pSample++;
2573- }
25742521 // Loop Start
2575- if (( pos = m_SpinLoopStart.GetPos32 ()) != 0 && sample.nLoopEnd > 0 )
2522+ if ( int pos = m_SpinLoopStart.GetPos32 (); pos != 0 && sample.nLoopEnd > 0 && sample. HasSampleData () )
25762523 {
2577- bool bOk = false ;
2578- const uint8 *p = pSample + sample.nLoopStart * inc;
2579- int find0 = (int )pSample[sample.nLoopEnd *inc-inc];
2580- int find1 = (int )pSample[sample.nLoopEnd *inc];
2581- // Find Next LoopStart Point
2582- if (pos > 0 )
2583- {
2584- for (i = sample.nLoopStart + 1 ; i + 16 < sample.nLoopEnd ; i++)
2585- {
2586- p += inc;
2587- bOk = sample.uFlags [CHN_PINGPONGLOOP] ? MPT_BidiStartCheck (p[0 ], p[inc], p[inc*2 ]) : MPT_LoopCheck (find0, find1, p[0 ], p[inc]);
2588- if (bOk) break ;
2589- }
2590- } else
2591- // Find Prev LoopStart Point
2524+ if (SmpLength i = SampleEdit::FindLoopStart (sample, false , pos > 0 , moveLoop); i < sample.nLength )
25922525 {
2593- for (i = sample.nLoopStart ; i; )
2526+ if (!m_startedEdit && lastScrollbar != scrollBar)
2527+ PrepareUndo (moveLoop ? " Move Loop" : " Set Loop Start" );
2528+ if (moveLoop)
25942529 {
2595- i--;
2596- p -= inc;
2597- bOk = sample.uFlags [CHN_PINGPONGLOOP] ? MPT_BidiStartCheck (p[0 ], p[inc], p[inc*2 ]) : MPT_LoopCheck (find0, find1, p[0 ], p[inc]);
2598- if (bOk) break ;
2530+ sample.nLoopEnd = i + (sample.nLoopEnd - sample.nLoopStart );
2531+ wsprintf (s, _T (" %u" ), sample.nLoopEnd );
2532+ m_EditLoopEnd.SetWindowText (s);
25992533 }
2600- }
2601- if (bOk)
2602- {
2603- if (!m_startedEdit && lastScrollbar != scrollBar) PrepareUndo (" Set Loop Start" );
26042534 sample.nLoopStart = i;
26052535 wsprintf (s, _T (" %u" ), sample.nLoopStart );
26062536 m_EditLoopStart.SetWindowText (s);
@@ -2610,34 +2540,18 @@ void CCtrlSamples::OnVScroll(UINT nCode, UINT, CScrollBar *scrollBar)
26102540 m_SpinLoopStart.SetPos (0 );
26112541 }
26122542 // Loop End
2613- if (( pos = m_SpinLoopEnd.GetPos32 ()) != 0 )
2543+ if ( int pos = m_SpinLoopEnd.GetPos32 (); pos != 0 && sample. HasSampleData () )
26142544 {
2615- bool bOk = false ;
2616- const uint8 *p = pSample + sample.nLoopEnd * inc;
2617- int find0 = (int )pSample[sample.nLoopStart *inc];
2618- int find1 = (int )pSample[sample.nLoopStart *inc+inc];
2619- // Find Next LoopEnd Point
2620- if (pos > 0 )
2621- {
2622- for (i = sample.nLoopEnd + 1 ; i <= sample.nLength ; i++, p += inc)
2623- {
2624- bOk = sample.uFlags [CHN_PINGPONGLOOP] ? MPT_BidiEndCheck (p[0 ], p[inc], p[inc*2 ]) : MPT_LoopCheck (find0, find1, p[0 ], p[inc]);
2625- if (bOk) break ;
2626- }
2627- } else
2628- // Find Prev LoopEnd Point
2545+ if (SmpLength i = SampleEdit::FindLoopEnd (sample, false , pos > 0 , moveLoop); i > 0 )
26292546 {
2630- for (i = sample.nLoopEnd ; i > sample.nLoopStart + 16 ; )
2547+ if (!m_startedEdit && lastScrollbar != scrollBar)
2548+ PrepareUndo (moveLoop ? " Move Loop" : " Set Loop End" );
2549+ if (moveLoop)
26312550 {
2632- i--;
2633- p -= inc;
2634- bOk = sample.uFlags [CHN_PINGPONGLOOP] ? MPT_BidiEndCheck (p[0 ], p[inc], p[inc*2 ]) : MPT_LoopCheck (find0, find1, p[0 ], p[inc]);
2635- if (bOk) break ;
2551+ sample.nLoopStart = i - (sample.nLoopEnd - sample.nLoopStart );
2552+ wsprintf (s, _T (" %u" ), sample.nLoopStart );
2553+ m_EditLoopStart.SetWindowText (s);
26362554 }
2637- }
2638- if (bOk)
2639- {
2640- if (!m_startedEdit && lastScrollbar != scrollBar) PrepareUndo (" Set Loop End" );
26412555 sample.nLoopEnd = i;
26422556 wsprintf (s, _T (" %u" ), sample.nLoopEnd );
26432557 m_EditLoopEnd.SetWindowText (s);
@@ -2647,35 +2561,18 @@ void CCtrlSamples::OnVScroll(UINT nCode, UINT, CScrollBar *scrollBar)
26472561 m_SpinLoopEnd.SetPos (0 );
26482562 }
26492563 // Sustain Loop Start
2650- if (( pos = m_SpinSustainStart.GetPos32 ()) != 0 && sample.nSustainEnd > 0 )
2564+ if ( int pos = m_SpinSustainStart.GetPos32 (); pos != 0 && sample.nSustainEnd > 0 && sample. HasSampleData () )
26512565 {
2652- bool bOk = false ;
2653- const uint8 *p = pSample + sample.nSustainStart * inc;
2654- int find0 = (int )pSample[sample.nSustainEnd *inc-inc];
2655- int find1 = (int )pSample[sample.nSustainEnd *inc];
2656- // Find Next Sustain LoopStart Point
2657- if (pos > 0 )
2658- {
2659- for (i = sample.nSustainStart + 1 ; i + 16 < sample.nSustainEnd ; i++)
2660- {
2661- p += inc;
2662- bOk = sample.uFlags [CHN_PINGPONGSUSTAIN] ? MPT_BidiStartCheck (p[0 ], p[inc], p[inc*2 ]) : MPT_LoopCheck (find0, find1, p[0 ], p[inc]);
2663- if (bOk) break ;
2664- }
2665- } else
2666- // Find Prev Sustain LoopStart Point
2566+ if (SmpLength i = SampleEdit::FindLoopStart (sample, true , pos > 0 , moveLoop); i < sample.nLength )
26672567 {
2668- for (i = sample.nSustainStart ; i; )
2568+ if (!m_startedEdit && lastScrollbar != scrollBar)
2569+ PrepareUndo (moveLoop ? " Move Sustain Loop" : " Set Sustain Loop Start" );
2570+ if (moveLoop)
26692571 {
2670- i--;
2671- p -= inc;
2672- bOk = sample.uFlags [CHN_PINGPONGSUSTAIN] ? MPT_BidiStartCheck (p[0 ], p[inc], p[inc*2 ]) : MPT_LoopCheck (find0, find1, p[0 ], p[inc]);
2673- if (bOk) break ;
2572+ sample.nSustainEnd = i + (sample.nSustainEnd - sample.nSustainStart );
2573+ wsprintf (s, _T (" %u" ), sample.nSustainEnd );
2574+ m_EditSustainEnd.SetWindowText (s);
26742575 }
2675- }
2676- if (bOk)
2677- {
2678- if (!m_startedEdit && lastScrollbar != scrollBar) PrepareUndo (" Set Sustain Loop Start" );
26792576 sample.nSustainStart = i;
26802577 wsprintf (s, _T (" %u" ), sample.nSustainStart );
26812578 m_EditSustainStart.SetWindowText (s);
@@ -2685,34 +2582,18 @@ void CCtrlSamples::OnVScroll(UINT nCode, UINT, CScrollBar *scrollBar)
26852582 m_SpinSustainStart.SetPos (0 );
26862583 }
26872584 // Sustain Loop End
2688- if (( pos = m_SpinSustainEnd.GetPos32 ()) != 0 )
2585+ if ( int pos = m_SpinSustainEnd.GetPos32 (); pos != 0 && sample. HasSampleData () )
26892586 {
2690- bool bOk = false ;
2691- const uint8 *p = pSample + sample.nSustainEnd * inc;
2692- int find0 = (int )pSample[sample.nSustainStart *inc];
2693- int find1 = (int )pSample[sample.nSustainStart *inc+inc];
2694- // Find Next LoopEnd Point
2695- if (pos > 0 )
2696- {
2697- for (i = sample.nSustainEnd + 1 ; i + 1 < sample.nLength ; i++, p += inc)
2698- {
2699- bOk = sample.uFlags [CHN_PINGPONGSUSTAIN] ? MPT_BidiEndCheck (p[0 ], p[inc], p[inc*2 ]) : MPT_LoopCheck (find0, find1, p[0 ], p[inc]);
2700- if (bOk) break ;
2701- }
2702- } else
2703- // Find Prev LoopEnd Point
2587+ if (SmpLength i = SampleEdit::FindLoopEnd (sample, true , pos > 0 , moveLoop); i > 0 )
27042588 {
2705- for (i = sample.nSustainEnd ; i > sample.nSustainStart + 16 ; )
2589+ if (!m_startedEdit && lastScrollbar != scrollBar)
2590+ PrepareUndo (moveLoop ? " Move Sustain Loop" : " Set Sustain Loop End" );
2591+ if (moveLoop)
27062592 {
2707- i--;
2708- p -= inc;
2709- bOk = sample.uFlags [CHN_PINGPONGSUSTAIN] ? MPT_BidiEndCheck (p[0 ], p[inc], p[inc*2 ]) : MPT_LoopCheck (find0, find1, p[0 ], p[inc]);
2710- if (bOk) break ;
2593+ sample.nSustainStart = i - (sample.nSustainEnd - sample.nSustainStart );
2594+ wsprintf (s, _T (" %u" ), sample.nSustainStart );
2595+ m_EditSustainStart.SetWindowText (s);
27112596 }
2712- }
2713- if (bOk)
2714- {
2715- if (!m_startedEdit && lastScrollbar != scrollBar) PrepareUndo (" Set Sustain Loop End" );
27162597 sample.nSustainEnd = i;
27172598 wsprintf (s, _T (" %u" ), sample.nSustainEnd );
27182599 m_EditSustainEnd.SetWindowText (s);
@@ -2721,9 +2602,8 @@ void CCtrlSamples::OnVScroll(UINT nCode, UINT, CScrollBar *scrollBar)
27212602 }
27222603 m_SpinSustainEnd.SetPos (0 );
27232604 }
2724- NoSample:
27252605 // FineTune / C-5 Speed
2726- if (( pos = m_SpinFineTune.GetPos32 ()) != 0 )
2606+ if ( int pos = m_SpinFineTune.GetPos32 (); pos != 0 )
27272607 {
27282608 if (!m_startedEdit && lastScrollbar != scrollBar)
27292609 PrepareUndo (" Finetune" );
@@ -2930,8 +2810,7 @@ void CCtrlSamples::OnXFade()
29302810 CSampleXFadeDlg dlg (this , sample);
29312811 if (dlg.DoModal () == IDOK)
29322812 {
2933- const SmpLength loopStart = dlg.m_useSustainLoop ? sample.nSustainStart : sample.nLoopStart ;
2934- const SmpLength loopEnd = dlg.m_useSustainLoop ? sample.nSustainEnd : sample.nLoopEnd ;
2813+ const auto [loopStart, loopEnd] = dlg.m_useSustainLoop ? sample.GetSustainLoop () : sample.GetLoop ();
29352814 const SmpLength maxSamples = std::min ({ sample.nLength , loopStart, loopEnd / 2 });
29362815 SmpLength fadeSamples = dlg.PercentToSamples (dlg.m_fadeLength );
29372816 LimitMax (fadeSamples, maxSamples);
0 commit comments