17#include "../../SpectrumAnalyst.h"
22#include "../../ProjectSettings.h"
23#include "../../ProjectWindow.h"
24#include "../../RefreshCode.h"
25#include "../../SelectUtilities.h"
27#include "../../SpectralDataManager.h"
28#include "../../TrackArtist.h"
29#include "../../TrackPanelAx.h"
30#include "../../TrackPanel.h"
31#include "../../TrackPanelDrawingContext.h"
32#include "../../TrackPanelMouseEvent.h"
36#include "../../prefs/SpectrogramSettings.h"
37#include "../../../images/Cursors.h"
38#include "../playabletrack/wavetrack/ui/SpectrumView.h"
71 float minFreq, maxFreq;
75 return trackTopEdge + wxInt64((1.0 - p) * trackHeight);
82 wxInt64 mouseYCoordinate,
86 const double rate = wt->
GetRate();
98 float minFreq, maxFreq;
99 cache.GetBounds(*wt, minFreq, maxFreq);
101 const double p = double(mouseYCoordinate - trackTopEdge) / trackHeight;
110 wxInt64 posTime = viewInfo.
PositionToTime(mousePosX, trackTopEdgeX);
129 pChannelView->
FindTrack()->TypeSwitch<
bool>(
132 return settings.SpectralSelectionEnabled();
137 static auto crosshairCursor =
138 ::MakeCursor(wxCURSOR_IBEAM, CrosshairCursorXpm, 16, 16);
139 return &*crosshairCursor;
144 std::shared_ptr<StateSaver> pStateSaver,
145 const std::shared_ptr<ChannelView> &pChannelView,
148 const std::shared_ptr<SpectralData> &pSpectralData,
150) : mpStateSaver{ move(pStateSaver) }
151 , mpSpectralData(pSpectralData)
152 , mpView{ pChannelView }
154 const wxMouseState &state = st.
state;
155 auto pTrack = pChannelView->FindTrack().get();
156 auto wt =
dynamic_cast<WaveTrack *
>(pTrack);
177 template <
class A,
class B,
class DIST >
bool within(
A a, B b, DIST d)
179 return (a > b - d) && (a < b + d);
184 const double minFrequency = 1.0;
185 const double maxFrequency = (rate / 2.0);
186 const double frequency =
188 std::max(minFrequency, center));
190 std::min(frequency / minFrequency, maxFrequency / frequency);
230 const auto pView =
mpView.lock();
234 wxMouseEvent &
event = evt.
event;
236 const auto pTrack = sTrack.get();
250 const auto pView =
mpView.lock();
254 wxMouseEvent &
event = evt.
event;
256 const auto pTrack = sTrack.get();
262 auto posXToHopNum = [&](
int x0){
263 double posTime = viewInfo.PositionToTime(x0,
mRect.x);
269 auto posYToFreqBin = [&](
int y0){
272 return static_cast<int>(
std::round(resFreqBin));
275 auto drawCircle = [&](
int h0,
int bm){
283 for (
int i = h0 - h2; i <= h0 + h2; i++)
288 for (
int i = h0 - b2; i <= h0 + b2; i++)
295 radiusError += bChange;
297 if (((radiusError << 1) + hChange) > 0)
300 radiusError += hChange;
308 int dest_xcoord = std::clamp(event.m_x,
mRect.x + 10,
mRect.x +
mRect.width);
309 int dest_ycoord = std::clamp(event.m_y,
mRect.y + 10,
mRect.y +
mRect.height);
311 int h1 = posXToHopNum(dest_xcoord);
312 int b1 = posYToFreqBin(dest_ycoord);
314 mbCtrlDown =
event.ControlDown() ||
event.AltDown();
325 int h0 = posXToHopNum(src_xcoord);
326 int b0 = posYToFreqBin(src_ycoord);
329 int dh = abs(h1-h0), sh = h0<h1 ? 1 : -1;
330 int db = -abs(b1-b0), sb = b0<b1 ? 1 : -1;
331 int err = dh+db, err2;
335 if (h0 == h1 && b0 == b1)
338 if (err2 * 2 >= db) { err += db; h0 += sh; }
339 if (err2 * 2 <= dh) { err += dh; b0 += sb; }
345 if(
auto *sView =
dynamic_cast<SpectrumView*
>(pView.get())){
349 if(resFreqBin != - 1)
358 for(
auto & bins: binsToWork)
359 drawCircle(h0, bins);
365 mpSpectralData->coordHistory.push_back(std::make_pair(dest_xcoord, dest_ycoord));
374 return { tip, pCursor };
389 XO(
"Erased selected area" ),
390 XO(
"Erased selected area" ) );
395 XO(
"Selected area using Brush Tool" ),
396 XO(
"Brush tool selection" ) );
411 const wxRect &rect,
unsigned iPass )
414 auto& dc = context.
dc;
418 dc.SetBrush( *wxTRANSPARENT_BRUSH );
419 dc.SetPen( *wxYELLOW_PEN );
426 auto pView =
mpView.lock();
430 return pView->FindTrack();
@ SELECTION_RESIZE_REGION
static Settings & settings()
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
bool within(A a, B b, DIST d)
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
std::shared_ptr< SelectionStateChanger > mSelectionStateChanger
std::shared_ptr< StateSaver > mpStateSaver
long long mSampleCountLowerBound
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *pProject) override
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
void Enter(bool forward, AudacityProject *pProject) override
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
BrushHandle(const BrushHandle &)
double mFreqSnappingRatio
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
void HandleHopBinData(int hopNum, int freqBinNum)
std::weak_ptr< ChannelView > mpView
double mOvertonesThreshold
Result Cancel(AudacityProject *) override
bool Escape(AudacityProject *pProject) override
std::weak_ptr< Track > FindTrack()
long long mSampleCountUpperBound
std::shared_ptr< SpectralData > mpSpectralData
virtual bool IsSpectral() const
std::shared_ptr< Track > FindTrack()
float PositionToValue(float pp) const
float ValueToPosition(float val) const
void PushState(const TranslatableString &desc, const TranslatableString &shortDesc)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
Holds various per-project settings values, and sends events to the project when certain values change...
int GetBrushRadius() const
bool IsSmartSelection() const
static std::vector< int > FindHighestFrequencyBins(WaveTrack *wt, long long int startSC, int hopSize, double threshold, int targetFreqBin)
static int FindFrequencySnappingBin(const WaveChannel &channel, long long startSC, int hopSize, double threshold, int targetFreqBin)
void GetBounds(const WaveTrack &wt, float &min, float &max) const
static SpectrogramBounds & Get(WaveTrack &track)
Get either the global default settings, or the track's own if previously created.
static SpectrogramSettings & Get(const WaveTrack &track)
Mutative access to attachment even if the track argument is const.
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
std::shared_ptr< Subclass > Lock(const std::weak_ptr< Subclass > &wTrack)
static TrackList & Get(AudacityProject &project)
static TrackPanel & Get(AudacityProject &project)
Holds a msgid for the translation catalog; may also bind format arguments.
static ViewInfo & Get(AudacityProject &project)
A Track that contains audio waveform data.
double GetRate() const override
sampleCount TimeToLongSamples(double t0) const
double PositionToTime(int64 position, int64 origin=0, bool ignoreFisheye=false) const
Positions or offsets within audio files need a wide type.
long long as_long_long() const
Namespace containing an enum 'what to do on a refresh?'.
bool isSpectralSelectionView(const ChannelView *pChannelView)
wxCursor * CrosshairCursor()
double PositionToFrequency(const WaveTrack *wt, bool maySnap, wxInt64 mouseYCoordinate, wxInt64 trackTopEdge, int trackHeight)
void SetIfNotNull(T *pValue, const T Value)
long long PositionToLongSample(const WaveTrack *wt, const ViewInfo &viewInfo, int trackTopEdgeX, int mousePosX)
double findMaxRatio(double center, double rate)
wxInt64 FrequencyToPosition(const WaveTrack *wt, double frequency, wxInt64 trackTopEdge, int trackHeight)
Converts a frequency to screen y position.
fastfloat_really_inline void round(adjusted_mantissa &am, callback cb) noexcept